如何在react-redux中成功执行异步函数后调用组件方法?

时间:2018-06-04 18:08:37

标签: javascript reactjs react-redux

主要组成部分:

class GettingStarted extends React.Component {

  state = {
    incompleteStage: ['a', 'b', 'c']
  };


  next = () => {
    const data = this.state.incompleteStage;
    // Everytime when next() gets called removes the first stage 
    // from incompleteStage.
    this.setState({
      incompleteStage: [...data.slice(1)]
    });
  }

  render() {
    const { incompleteStage } = this.state;
    const { isSmallDevice, me } = this.props;
    if (incompleteStage.length === 0) return null;

    return (
      <div>
       <Child {...props}/>
      </div>
    );
  }
}

const mapStateToProps = (state) => ({
  postStageLoading: state.auth.postStageLoading,
  postStageError: state.auth.postStageError
});

const mapDispatchToProps = (dispatch) => bindActionCreators({}, dispatch);

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(GettingStarted);

子组件:

class Child extends React.Component {
  handleSubmit = event => {
    event && event.preventDefault();
    const { postStage } = this.props;
    const { next, name, nextStage } = this.props;
    postStage(name, nextStage);   // async call
    next();
  }

  render() {
    const { me } = this.props;

    return (
      <div >
        <Typography
          Welcome {me ? me.nameOrEmail : ''}!
        </Typography>
      </div> 
    );
  }
}

const mapStateToProps = (state) => ({

});

const mapDispatchToProps = (dispatch) => bindActionCreators({
  postStage
}, dispatch);

export default withStyles(styles)(connect(
  mapStateToProps,
  mapDispatchToProps
)(Child));

modules / index.js(因为它太长了,我写得很重要)

export default (state = initialState, {type, payload}) => {
    case types.POST_STAGE_REQUEST:
      return Object.assign({}, state, {
        postStageLoading: true
      });
    case types.POST_STAGE_SUCCESS:
      return Object.assign({}, state, {
        postStageLoading: false,
      });
    case types.POST_STAGE_FAILURE:
      return Object.assign({}, state, {
        postStageLoading: false,
        postStageError: payload
      });
}
export const postStage = (currentStage) => {
  return dispatch => {
    request.post('/stage', {stage: currentStage}, dispatch)
    .then(({ data }) => {
      if (data.success) {
        dispatch({
          type: types.POST_STAGE_SUCCESS,
        });
        dispatch(push(nextStage));
    }
 }
};

因此,如果您可以在Child 中看到,我必须在成功调用帖子请求后调用next()方法(主要组件)。 {{1} }。 (我已经跳过了一些代码,因为它太冗长了)。如果我在next()之后拨打电话(就像我在儿童时所做的那样),我无法保证api电话会成功。我在哪里以及如何称呼它?

我在Child中有一个按钮,它有一个eventHandler - postStage

3 个答案:

答案 0 :(得分:1)

可能有一些简洁的方法来纠缠异步调用来执行此操作,但坦率地说,我只是将GettingStarted本地状态放入Redux存储区。然后更改reducer中POST_STAGE_SUCCESS操作的相关状态,或者调度第二个操作并使用reducer中的状态更改状态。这也将防止Redux状态更新比本地组件状态更快的任何竞争条件(反之亦然),从而导致不同的效果。

答案 1 :(得分:1)

您应该将incompleteStage存储在商店中,让减速器更改它。异步完成时调度操作,reducer应更改incompleteStage数组,以便组件更新它的道具。

答案 2 :(得分:0)

你应该知道承诺并相应地构建应用程序。

你应该运行像这样的代码

postStage(name,nextStage).then(()=&gt; next());