reactjs - 如何在 redux 操作完成并更新 redux 存储后触发回调?
问题描述
大约一年前我学会了React
,直到最近才大量使用它们。Redux
我惊讶地发现 和 都有很多React
变化Redux
。
我注意到的第一件事是我不能再使用componentWillReceiveProps
生命周期方法,它告诉我我需要使用一些getDerivedStateFromProps
不能真正解决我当前问题的奇怪方法。
基本上,我有一个寄存器功能,它dispatches
3 actions
-REGISTER_REQUEST
和. 我的 userReducer 中也有 3 个标志 - , , .REGISTER_SUCCESS
REGISTER_FAIL
registering
registered
registerError
在我的Register
组件中,我想做以下事情:
- 为 true时
registering
,添加加载动画 - 当
registering
为假registered
为真时,将用户重定向到/profile
路由 - 当
registerError
为真时,从 获取错误redux store
并将其设置在组件的state
.
我的第一种方法如下:
componentWillReceiveProps() {
if(this.props.user){
if(this.props.user.registered && !this.props.user.registering){
this.props.history.push("/jobs")
}
}
if(this.props.user.registerError){
this.setState({error: this.props.user.registerErrorMessage})
}
}
这并没有像我预期的那样奏效。正如我上面提到的,它告诉我我不再被允许使用componentWillRecieveProps
.
我的下一个猜测是使用该componentDidUpdate
方法,但在该方法中,我不能调用setState
,因为它会导致臭名昭著的state loop error
. 我以前解决过这个错误,但不是没有做很多我不喜欢的骇人听闻的事情。
我最终通过创建一个history helper
允许我从组件外部重定向用户(注册函数)来解决这个问题,但这最终导致了更多的问题,react router
并且它没有解决我设置registerErrorMessage
组件的问题state
。
那么在 React 和 Redux 中这样做的正确方法是什么?我真的很想避免使用 hacky 技巧来解决这些问题,因为它们几乎总是会在以后出现并咬我的屁股。
解决方案
虽然我看不出为什么需要将错误消息保存在组件的状态中,而不是仅仅从 redux 存储中获取错误并将其显示给用户,但您可以调用this.setState
内部componentDidUpdate
函数,但要避免无限循环状态更新和重新渲染,你需要有条件地更新状态。
假设registerError
redux store 内部和error
组件的 state 最初都是null
内部componentDidUpdate
函数,检查是否this.state.error
等于从 redux store 注册错误。如果它们不相等,则更新状态。
componentDidUpdate(prevProps, prevState) {
if (this.state.error != this.props.registerError) {
this.setState({ error: this.props.registerError });
}
}
演示:
在这个演示中,有一个Register
组件调度一个动作来从 jsonplaceholder API 获取用户。当 HTTP 请求开始时,REGISTER_REQUEST
将派发操作,registering
将 redux 存储中的状态设置为 true。如果成功获取用户,REGISTER_SUCCESS
则分派操作。如果发生错误,REGISTER_ERROR
则调度操作。当出现错误时,该错误会保存在Register
组件内部的状态中,并且也会显示给用户。
为了在发出 HTTP 请求时产生错误,我将 API URL 从
"https://jsonplaceholder.typicode.com/users/1" // correct URL
到
"https://jsonplaceholder.typicode.com/user/1" // incorrect URL
推荐阅读
- android - 如何在 Firebase android 中添加多组数据而不覆盖它们
- webforms - 在新标签页中打开所有浏览器不工作的链接
- docker - Git 2.8 无法更新子模块
- ios - 为什么我在 Storyboard (Xcode) 中所做的更改没有反映在我的应用程序上?
- c# - TechTalk.Specflow.dll 中的 ConfigurationErrorsException
- visual-studio-code - 如何通过命令将预览选项卡更改为打开的选项卡?
- ios - swift 4、使用 UIActivityViewController 将图像分享到 facebook 和其他应用程序崩溃
- flutter - 如何在 CustomMultiChildLayout 中具有动态高度?
- cordova - 如何在 Ionic 2 中使用 iFrame 加载 URL
- javascript - 如何在 Reactjs 的自动建议列表中应用突出显示匹配字符?