Как вызвать метод компонента после успешной асинхронной функции вact-redux? - PullRequest
0 голосов
/ 04 июня 2018

Основной компонент:

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() (основного компонента) только после успешного вызова почтового запроса. next().(Я пропустил немного кода, потому что он слишком длинный).Если я позвонил сразу после postStage (как я это сделал в Child), у меня нет никаких гарантий, что вызов API успешен.Где и как я могу это назвать?

У меня есть кнопка в Child, у которой есть eventHandler - handleSubmit

Ответы [ 3 ]

0 голосов
/ 04 июня 2018

Возможно, есть какой-то изящный способ справиться с асинхронными вызовами, но, честно говоря, я бы просто поместил локальное состояние GettingStarted в ваше хранилище Redux.Затем либо измените соответствующее состояние в действии POST_STAGE_SUCCESS в редукторе, либо отправьте второе действие и измените состояние в соответствии с этим в редукторе.Это также предотвратит любые состояния гонки, когда состояние Redux обновляется быстрее, чем состояние локального компонента (или наоборот), вызывая различные эффекты.

0 голосов
/ 04 июня 2018

Вы должны сохранить незаполненный этап в вашем магазине и позволить редукторам изменить его.Отправьте действие, когда асинхронный режим завершится, и редуктор должен изменить массив incompleteStage, чтобы ваш компонент обновил свои реквизиты.

0 голосов
/ 04 июня 2018

вы должны знать об обещаниях и соответственно структурировать приложение.

вы должны запускать такой код

postStage (name, nextStage) .then (() => next ());

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...