【问题标题】:recompose withHandlers ... asynchronously?异步重构 withHandlers ...?
【发布时间】:2017-06-01 21:27:52
【问题描述】:

是否可以/安全地将 withHandlers 与 Promise 一起使用? 例如:

withHandlers({
    onChange: props => event => {
      props.callAPI(props.data)
        .then(data => props.updateData(data))
    },
...

谢谢!

【问题讨论】:

    标签: reactjs recompose


    【解决方案1】:

    但是当我们这样使用时会出现一些问题:

    compose(
      withState('loginStatus', 'setLoginStatus', {loading: false, error:null}),
      withHandlers({
        loginUserMutation: props => async args => {
          try {
            props.setLoginStatus({loading: true, error: null});
            await props.loginUser(args);
          } catch(error) {
            props.setLoginStatus({...props.loginStatus, error});
          } finally {
            props.setLoginStatus({...props.loginStatus, loading: false});
          }
        }
      })
    )
    

    因为props引用确实在我们await props.loginUser(args)之后丢失了。那我们以后再用就是错了。

    我们应该注意不要像上面那样使用它。


    【讨论】:

    • 我不明白props 引用丢失了。它不是,你甚至不使用它。也许你的意思是 finally 没有运行。如果loginUser(args) 更改应用程序状态从而卸载包装的组件,则这是有道理的。或者你能详细说明一下吗?我们广泛使用recompose,ew 对此绝对没有问题。
    • 我的意思是参数props等于this.props,但是在你setLoginStatus and await loginUser之后(setLoginStatus就像this.setState),那么参数props已经不等于this.props.... 就像:const props = this.props; this.setState({xxx}); api().then(_ => console.log(props == this.props)); 它将记录 false...
    • 我建议不要将 recompose 视为一个有状态的组件(并且根本不要考虑 this。您的 await props.loginUser(args); 将更改更高组件中的道具,这将触发重新计算组件树。这就是为什么在此之后await 道具可能会有所不同,如果 loginUser 在更高的组件层中更改道具(但前提是您向下传递此信息)。这就是为什么通常如果您使用例如分支(决定是否显示登录名或用户数据),在 loginUser 之后,您的组件将被卸载,之后的任何内容都将变为无操作。
    【解决方案2】:

    经过一些测试,我意识到它运行良好。 Recompose 使用纯组件构建的岩石。

    这是完全有效的并且工作得很好。

    const enhWithHandlers = withHandlers({
      loginUserMutation: props => args => {
        props.updateMutationState(loading: true, error: null });
        props.loginUser(args)
          .then(() =>
            props.updateMutationState({loading: false, error: null }))
          .catch(err =>
            props.updateMutationState({ loading: false, error: err }));
      }
    },
    ...
    // then compose like
    export default compose(
      reduxConnect,
      gqlConnectLogin,
      gqlConnectRegister,
      enhWithState,
      enhWithHandlers
    )(UserLoginRegister);
    

    它帮助我克服了将带有Apollo client 的graphQl 突变结果反映到包装组件的能力不足的问题。这可以完美地处理它,并且不需要组件本身的副作用。

    【讨论】:

    • 是的,安全可行
    猜你喜欢
    • 2014-02-23
    • 2017-07-24
    • 2018-11-16
    • 1970-01-01
    • 2012-07-15
    • 2018-04-20
    • 2020-03-17
    • 1970-01-01
    • 2017-04-21
    相关资源
    最近更新 更多