Функция обработчика событий компонента React не получила новейшее значение из Redux Store - PullRequest
0 голосов
/ 21 марта 2020

Я работаю над простым приложением в качестве моего побочного проекта, чтобы лучше понять React и Redux. Я обнаружил проблему при вызове asyn c action creator, который обновил значение в редукторе, но когда я пытаюсь получить доступ к значению в компонентной функции обработчика событий, оно все еще имеет старое значение.

Вот мой создатель действия:

export const assignUsername = username => async dispatch => {
  dispatch({type: types.ASSIGN_USERNAME_REQUEST})

  await axios({
    method: "PUT",
    url: "/v1/user/username",
    data: {
      username: username
    }
  })
  .then(response => {
    if(response.data && response.data.success){
      dispatch({
        type: types.ASSIGN_USERNAME_SUCCESS,
        payload: response.data.result
      })
    }else{
      dispatch({type: types.ASSIGN_USERNAME_FAILED})
      dispatch(httpPopUpError(response.status, response.data.message))
    }
  })
}

Вот редуктор:

var initialState = {
  loading: false,
  result: null,
  error: false
};

function AuthReducer(state = initialState, action) {
  switch (action.type) {
    case types.ASSIGN_USERNAME_REQUEST:
      return {
        ...state,
        loading: true,
        error: false
      }
    case types.ASSIGN_USERNAME_FAILED:
      return {
        ...state,
        loading: false,
        error: true
      }
    case types.ASSIGN_USERNAME_SUCCESS:
      return {
        ...state,
        loading: false,
        result: action.payload,
        error: false
      }
    default:
      return state;
  }
}

Вот функция обработчика события, которая вызывает создателя действия и обращается к хранилищу:

  handleAssignUsername = (e) => {
    e.preventDefault();

    formValidator(this.state.form)
      .then(validatedForm => {
        this.setState({
          ...this.state,
          form: validatedForm
        }, () => {
          this.props.assignUsername(this.state.form.username.value)
          .then(() => {
            if(!this.props.AuthReducer.error) {
              this.props.history.push("/")
            }
          })
        })
      })
      .catch(errorForm => {
        this.setState({
          ...this.state,
          form: errorForm
        })
      })
  }

As Вы можете видеть выше, я обращаюсь к "this.props.AuthReducer.error", чтобы определить, есть ли у него ошибка или нет, и затем решаю перенаправить. Но значение ошибки по-прежнему false , хотя в Redux Devtools я видел, что оно уже превращается в true

Я очень признателен, если кто-то может помочь, или, возможно, предложить более элегантный подход, если мой не правильный подход. Спасибо.

примечание: я попробовал подобный подход в моем другом проекте, и он отлично работает. Это то, что меня смущает, потому что иногда это работает, иногда нет.

РЕДАКТИРОВАТЬ: Я попробовал предложение от Hemanath , но когда я утешаю журнал ошибок, он по-прежнему имеет то же значение, даже если ошибка становится true в Магазине.

 componentDidUpdate(prevProps){
  console.log(prevProps.AuthReducer.error, "PREV");
  console.log(this.props.AuthReducer.error, "NOW");
  if(prevProps.AuthReducer.error === false && this.props.AuthReducer.error === true){
    this.props.history.push("/");
  }
}

Снимок экрана console.log И о перенаправлении в методе рендеринга Боюсь, что это не очень хороший подход, так как значение по умолчанию error равно FALSE, если я это сделаю, оно всегда будет перенаправлено.

Я хочу сделать AJAX сначала запрос, затем перенаправление, если ошибка все еще ложна.

1 Ответ

1 голос
/ 21 марта 2020

используйте componentDidUpdate метод жизненного цикла для отслеживания изменения значения this.props.AuthReducer.error и перенаправления оттуда на основе нового значения,

componentDidUpdate(prevProps){
  if(prevProps.AuthReducer.error === false && this.props.AuthReducer.error === true){
    this.props.history.push("/");
  }
}

или, как предлагается в комментарии, вы можете использовать Redirect компонент из react-router в методе render для перенаправления, как этот

render() {
    const { AuthReducer } = this.props;
    if (AuthReducer && AuthReducer.loading === false && AuthReducer.error === true) {
      return <Redirect to='/' />;
    }
    return (
      <div>....</div>
    );
  }
...