如何在 redux 操作完成并更新 redux 存储后触发回调?

How to trigger a callback after a redux action finishes and updates redux store?

我大约一年前学习了 ReactRedux,直到最近才大量使用它们。我惊讶地发现 ReactRedux.

都有不少变化

我注意到的第一件事是我不能再使用 componentWillReceiveProps 生命周期方法,它告诉我我需要使用一些奇怪的 getDerivedStateFromProps 方法,这并不能真正解决我当前的问题.

基本上,我有一个寄存器函数dispatches 3 actions - REGISTER_REQUESTREGISTER_SUCCESSREGISTER_FAIL。我的 userReducer 中也有 3 个标志 - registeringregisteredregisterError.

在我的 Register 组件中,我想执行以下操作:

  1. registering为真时,添加加载动画
  2. registering为假且registered为真时,将用户重定向到/profile路由
  3. 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.setStatecomponentDidUpdate 函数中,但为了避免状态更新和重新渲染的无限循环,您需要有条件地更新状态。

假设 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