如何在 redux 操作完成并更新 redux 存储后触发回调?
How to trigger a callback after a redux action finishes and updates redux store?
我大约一年前学习了 React
和 Redux
,直到最近才大量使用它们。我惊讶地发现 React
和 Redux
.
都有不少变化
我注意到的第一件事是我不能再使用 componentWillReceiveProps
生命周期方法,它告诉我我需要使用一些奇怪的 getDerivedStateFromProps
方法,这并不能真正解决我当前的问题.
基本上,我有一个寄存器函数dispatches
3 actions
- REGISTER_REQUEST
、REGISTER_SUCCESS
和REGISTER_FAIL
。我的 userReducer 中也有 3 个标志 - registering
、registered
、registerError
.
在我的 Register
组件中,我想执行以下操作:
- 当
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 tricks 来解决这些问题,因为它们几乎总是在后来出现并咬我的屁股。
当props
由于redux store的变化而变化时,组件会重新渲染。所以你应该把这个逻辑放在 render
函数中。由于调用 setState
将调用另一个渲染器,因此您应该只使用 props
中的错误值,而不是将其保存在状态中。
尽管我看不出为什么需要将错误消息保存在组件状态中而不是仅仅从 redux 存储中获取错误并将其显示给用户,但您可以调用 this.setState
在 componentDidUpdate
函数中,但为了避免状态更新和重新渲染的无限循环,您需要有条件地更新状态。
假设 redux store 中的 registerError
和组件状态中的 error
最初都是 null
,在 componentDidUpdate
函数中,检查 this.state.error
是否相等是否从 redux 存储中注册错误。如果它们不相等,则更新状态。
componentDidUpdate(prevProps, prevState) {
if (this.state.error != this.props.registerError) {
this.setState({ error: this.props.registerError });
}
}
演示:
在 this demo 中有一个 Register
组件,它调度一个操作以从 jsonplaceholder API 中获取用户。当 HTTP 请求开始时,将调度 REGISTER_REQUEST
操作,将 redux 存储中的 registering
状态设置为 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
我大约一年前学习了 React
和 Redux
,直到最近才大量使用它们。我惊讶地发现 React
和 Redux
.
我注意到的第一件事是我不能再使用 componentWillReceiveProps
生命周期方法,它告诉我我需要使用一些奇怪的 getDerivedStateFromProps
方法,这并不能真正解决我当前的问题.
基本上,我有一个寄存器函数dispatches
3 actions
- REGISTER_REQUEST
、REGISTER_SUCCESS
和REGISTER_FAIL
。我的 userReducer 中也有 3 个标志 - registering
、registered
、registerError
.
在我的 Register
组件中,我想执行以下操作:
- 当
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 tricks 来解决这些问题,因为它们几乎总是在后来出现并咬我的屁股。
当props
由于redux store的变化而变化时,组件会重新渲染。所以你应该把这个逻辑放在 render
函数中。由于调用 setState
将调用另一个渲染器,因此您应该只使用 props
中的错误值,而不是将其保存在状态中。
尽管我看不出为什么需要将错误消息保存在组件状态中而不是仅仅从 redux 存储中获取错误并将其显示给用户,但您可以调用 this.setState
在 componentDidUpdate
函数中,但为了避免状态更新和重新渲染的无限循环,您需要有条件地更新状态。
假设 redux store 中的 registerError
和组件状态中的 error
最初都是 null
,在 componentDidUpdate
函数中,检查 this.state.error
是否相等是否从 redux 存储中注册错误。如果它们不相等,则更新状态。
componentDidUpdate(prevProps, prevState) {
if (this.state.error != this.props.registerError) {
this.setState({ error: this.props.registerError });
}
}
演示:
在 this demo 中有一个 Register
组件,它调度一个操作以从 jsonplaceholder API 中获取用户。当 HTTP 请求开始时,将调度 REGISTER_REQUEST
操作,将 redux 存储中的 registering
状态设置为 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