【问题标题】:How to wait for an action to complete?如何等待一个动作完成?
【发布时间】:2017-06-22 15:41:41
【问题描述】:

我是reactredux 的新手,一直在探索它与angular 的不同之处。

我正在尝试做一个简单的登录页面,但无法实现我想要的。从登录表单中获取用户名和密码后,我将其提交如下:

  submitHandler(e){
    e.preventDefault();
    var user = {
      name : this.state.username,
      password: this.state.password
    }
    this.props.authenticateUser(user);
    browserHistory.push('/home');
    this.setState({
      username:'',
      password:''
    })
  }

这里,authenticateUser 是我的 reducer(如下所示)中的一个函数,它从已经存在的用户列表中检查,然后是带有属性 isAuthenticated 的状态:

 case 'AUTHENTICATE_USER':
        var users = state.userslist;
        var payloadUser = action.payload;
        for (let i = 0; i < users.length; i++) {
            let user = users[i]
            if (user.name === payloadUser.name) {
                return {...state, isAuthenticated: true };
            }
        };
        return {...state, isAuthenticated: false };

现在在 Angular 中,我将等待此调用完成并检查此值是 true 还是 false,然后使用 angular-router 导航到主页。

但是我如何在react 中实现同样的效果。我在示例应用程序中使用react-router

我试图在我调用this.props.authenticateUser(user)submitHandler 函数下方检查isAuthenticated,但问题是,this.props.isAuthenticateUser 未更新并返回false,我已将其设置为@987654340 @ 在我的减速器中。

请告诉我在调用authenticateUser 函数后如何检查isAuthenticated,以便我可以继续我的主页路由。我是否必须使用promise 并等待redux 更新状态然后再次检查? (我知道 react 是一种单向路径,但它不会那样工作。)

此外,如果我的身份验证失败,如何在我的登录表单下方显示一个错误面板。我认为为错误面板使用一个组件,该组件以isAuthenticated 作为输入并检查是否为 false 以显示 (即 ngShow 就像在 Angular 中一样。) 但恐怕这行不通同样,因为我的状态不会及时更新。

我知道渲染函数会在状态发生任何变化时被调用。但我就是无法清楚地了解 React。

编辑:为简洁起见,我没有提供上面的动作创建者和完整的减速器,而只显示了身份验证用户的 switch case 操作。我的应用程序遵循原始的 redux 架构,包括操作、reducers、容器、组件等。

编辑: Github 链接here

【问题讨论】:

标签: reactjs redux react-router react-redux


【解决方案1】:

我更喜欢这样的代码:

const mapStateToProps = (state) => {
  return {
      isAuthenticated: state.isAuthenticated
  }
}

class Dashboard extends PureComponent {
  render() {
    const { isAuthenticated } = this.props

    return (
      <div>
        { isAuthenticated ? (
          <div>
            <p>Hello</p>
          </div>
        ) : (
          Login()
        )}
      </div>
    )
  }
}

来源:https://stackoverflow.com/a/56899814/3850405

除了@Nupur 的答案。 componentWillReceiveProps() 被认为是不安全的,方法名称现在是:UNSAFE_componentWillReceiveProps()

https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops

如果您喜欢这种方法,请改用componentDidUpdate(),初始渲染不会调用此方法。

componentDidUpdate(prevProps) {
    if (this.props.isAuthenticated ) {
        //perform code here
    }
}

https://reactjs.org/docs/react-component.html#componentdidupdate

【讨论】:

    【解决方案2】:

    我将尝试简要解释数据流在 Redux 应用程序中的工作原理:

    1. 不应直接从组件调用 reducer。您对身份验证用户的调用应该在一个操作中,并且应该从组件中分派。

    2. 定义动作时,可以给一个属性来定义动作的类型。例如,在这种情况下,它可能是type: AUTHENTICATE_USER

    3. action 完成后,redux store 用当前 state 和 action 调用 reducer where。这里可以根据action.type更新redux状态(上面第二个代码sn-p)

    4. 这是最重要的部分:您的组件需要有一个 mapStateToProps 方法,该方法将 Redux 状态中的值作为 props 传递到您的组件中。因此,随着状态的变化,道具会更新并且组件会重新渲染。要使用mapStateToProps,您需要从 react-redux 库中实现连接。 (https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options)

    为了实现你想要的,这是我的建议:

    1. 在组件的componentWillReceiveProps 方法中,检查props.isAuthenticated 并使用context.router.push() 导航用户是否已通过身份验证。

    2. 还在组件的render 方法中基于props.isAuthenticated 进行检查以显示错误消息。

    一些可能有用的链接:

    https://redux.js.org/basics/data-flow

    https://redux.js.org/basics/usage-with-react

    【讨论】:

    • 我确实有 mapStateToProps ,这是我注入 isAuthenticated 的地方,但问题是我不知道何时以及如何在发送操作后检查。因为在调用 isAuthenticated 之后立即检查 isAuthenticated,所以我没有定义。状态不会立即更新。
    • 在正确设置的 Redux 应用程序中,一旦您收到响应并调用 reducer,状态就会更新。通过查看您的代码,我可能会为您提供更多帮助。你可能在 Gihub 上有它吗?
    • 我现在正在工作。将代码推送到 github 并在我回家后与您分享链接。
    • 我已经用代码链接编辑了问题。请帮忙。
    • 我只是看了你的代码,我仍然坚持我之前的两个建议。 login-form.js 组件中的componentWillReceiveProps 方法将跟踪对道具的更改,您可以基于props.isAuthenticated 进行重定向。更多信息在这里:facebook.github.io/react/docs/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-06
    • 2017-04-18
    • 2019-11-06
    • 1970-01-01
    • 2019-01-16
    • 2015-07-05
    • 1970-01-01
    相关资源
    最近更新 更多