Навигация после заполнения формы способом react/redux

У меня есть действие, которое я призываю сохранитьBrand, которое выглядит следующим образом:

export function createBrand(props) {
  return function(dispatch) {
  postData('brands', props)
    .then(response => {
      dispatch({
        type: CREATE_BRAND_SUCCESS,
        payload: response
      });
      browserHistory.push("/brands/" + response.data.id);
    }).catch(err => {
      dispatch({type: CREATE_BRAND_ERROR});
    });
  }
}

Это вызывается из компонента. Мой вопрос заключается в томbrowserHistory.push("/brands/" + response.data.id);, который берет пользователя на страницу редактирования для бренда, который они только что сохранили. Является ли это подходящим способом / местом для этого? Должен ли я вместо этого отвечать на событие create_brand_success dispatch в самом компоненте? Если да, то как это будет выглядеть?

1 ответ

  1. В вашем подходе нет ничего плохого. Похоже, вы используете redux-thunk. Я не думаю, что это лучшая практика, чтобы реагировать на события в компоненте. Единственный способ сделать это (который я могу придумать) — создать пользовательское промежуточное программное обеспечение для проверки типа действия, а затем вызвать метод на вашем компоненте (пожалуйста, не делайте этого) или использовать ваши редукторы, чтобы сохранить некоторое состояние в компоненте responsesFromApi: [response1, response2].

    Подход, который мне нравится больше всего, заключается в использовании инструментов, которые позволяют мне запускать декларативные эффекты в редукторе, сохраняя чистоту редуктора. Redux Loop и мой собственный redux-funk позволяют это. Мне нравится этот подход, потому что ответ на вопрос «что происходит, когда это действие отправляется» можно найти в одном месте (редукторы). И декларативные эффекты легче тестировать.

    Таким образом, вы бы сделали это с redux-funk:

    // in component.js in mapDispatchToProps
    dispatch({
        type: REQUEST_CREATE_BRAND, ...brandObject
    });
    
    // in reducer
    const requestCreateBrand = brandName => postData('brands', brandName).catch(() => {type: CREATE_BRAND_FAILURE})
    
    const navigateToBrand = id => browserHistory.push(`/brands/${id}`)
    
    ...
    
    case REQUEST_CREATE_BRAND:
         call(action, [requestCreateBrand, [action.brandName]])
         return {...state, isRequesting: true}
    case CREATE_BRAND_SUCCESS:
         call(action, [navigateToBrand, [id]])
         return {...state, isRequesting: false, brands: {...state.brands, [action.brandId]: action.brand}
    

    Вы также можете создавать декларативные эффекты с помощью callфункции в Redux Saga