等待React Redux中的操作完成

时间:2017-02-05 17:43:03

标签: reactjs redux react-router react-redux

我是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

我尝试在isAuthenticated下面的submitHandler功能中检查this.props.authenticateUser(user) this.props.isAuthenticateUser,但问题是,false未更新并返回initialState },我在reducer中设置为isAuthenticated

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

此外,如果我的身份验证失败,如何在登录表单下方显示错误面板。我认为在错误面板中使用一个组件,它接受'rest_framework/api.html'作为输入,并检查是否为false以显示(即。在Angular中的ngShow。)但我担心会不能正常工作,因为我的州不会及时更新。

我知道渲染函数将在状态发生任何变化时被调用。但我无法清楚地把我的脑袋包裹起来。

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

编辑: Github链接here

2 个答案:

答案 0 :(得分:11)

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

  1. 不应直接从组件调用reducer。您对身份验证用户的调用应该在操作中,这应该是从组件调度的内容。

  2. 定义操作时,可以指定属性以定义操作类型。例如,在这种情况下,它可以是type: AUTHENTICATE_USER

  3. 完成操作后,redux存储会使用当前状态和操作调用reducer。在这里,redux状态可以根据action.type(上面的第二个代码片段)进行更新

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

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

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

    2. 同时根据组件props.isAuthenticated方法中的render进行检查,以显示错误消息。

    3. 一些可能有用的链接:

      http://redux.js.org/docs/basics/DataFlow.html

      http://redux.js.org/docs/basics/UsageWithReact.html

答案 1 :(得分:2)

我更喜欢这样的代码:

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