React Redux как использовать один редуктор для двух похожих действий в двух разных компонентах?

#reactjs #redux #react-redux

#reactjs #redux #react-redux

Вопрос:

У меня есть страница с двумя «умными» компонентами:

  • PageChildrenTabs
  • StaticPage

У меня есть функция действия:

 function fetchPage(slug) {
     return {
         type: 'FETCH_PAGE',
         payload: axios.get(PAGE_ENDPOINT   slug);
     }
}
  

И у меня есть редуктор:

 export function pageReducer(state={
    pending: false,
    payload: {data: {}},
    error: null
}, action) {
    switch(action.type) {
        case "FETCH_PAGE_PENDING": {
            return {...state, pending: true, payload: {data: {}}, error: null};
        }
        case "FETCH_PAGE_FULFILLED": {
            return {...state, pending: false, payload: action.payload, error: null};
        }
        case "FETCH_PAGE_REJECTED": {
            return {...state, pending: false, payload: {data: {}}, error: action.payload};
        }
    }
    return state;
}
  

Вызовы PageChildrenTabs this.props.fetchPage('about'); , в то время как StaticPage вызывает this.props.fetchPage('about/history'); . Обе эти функции выполняются одновременно, потому что они обе отображаются в родительском компоненте контейнера.

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

РЕДАКТИРОВАТЬ: Уточнил, в чем проблема.

Ответ №1:

Состояние Redux сохраняет все во всем приложении в одном дереве. Если вам нужно сохранить более одного из чего-либо, вы просто создаете массив или хэш. В этом случае вы, вероятно, захотите сохранить эти данные с помощью slug.

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

 function fetchPage(slug) {
     return {
         type: 'FETCH_PAGE',
         slug,
         payload: axios.get(PAGE_ENDPOINT   slug);
     }
}
  

Редуктор:

 function singlePageReducer(state={
    pending: false,
    payload: {data: {}},
    error: null
}, action) {
    switch(action.type) {
        case "FETCH_PAGE_PENDING": {
            return {...state, pending: true, payload: {data: {}}, error: null};
        }
        case "FETCH_PAGE_FULFILLED": {
            return {...state, pending: false, payload: action.payload, error: null};
        }
        case "FETCH_PAGE_REJECTED": {
            return {...state, pending: false, payload: {data: {}}, error: action.payload};
        }
    }
    return state;
}

export function pageReducer (state = {}, action) {
  if (["FETCH_PAGE_PENDING", "FETCH_PAGE_FULFILLED", "FETCH_PAGE_REJECTED"].indexOf(action.type) !== -1) {
    return { ...state,  [action.slug]: singlePageReducer(state[action.slug], action) };
  }
  return state; 
}
  

Вы можете объединить несколько редукторов вместе, чтобы создать симфонию данных. Посмотрите на пример todos для простого вдохновения.