Как разделить / разделить Redux Store между несколькими универсальными c компонентами? - PullRequest
0 голосов
/ 08 февраля 2020

У меня есть универсальный c компонент, который называется VendorResults. Я передаю строку поддержки каждому из этих общих c компонентов, таких как «Microsoft», «Apple» и т. Д. c.

    <ScrollView>
     <SearchResults/>
     <VendorResults vendor={"microsoft"}/>
     <VendorResults vendor={"oracle"}/>
    </ScrollView>

В этом универсальном c компоненте я передаю вендор в качестве параметра моим действиям Redux-Thunk следующим образом:

  componentDidMount() {
     const {vendor} = this.props;
     this.props.getVendorInformation(vendor);
  }

Вызывается вызов API, и Thunk действия отправляются. В конечном итоге данные попадают в Редуктор и сохраняются. Однако, когда у меня более одного универсального c компонента Vendor, какой бы асинхронный вызов c не завершился последним, создается впечатление, что он превалирует над всеми остальными. Например, если oracle заканчивает загрузку последней, состояние компонента Microsoft изменится и покажет oracle данные.

Действия

  export function getVendorInformation(vendor) {

  const url = `${VENDOR_URL}api/search/${vendor}`;

  return dispatch => {
    dispatch(getVendor());
    fetch(url)
      .then(blob => blob.json())
      .then(data => {
        dispatch(getVendorSuccess(data))
      })
      .catch(e => {
        console.log(e);
        dispatch(getVendorError(e.message))
      });
  };

Редуктор

export default function(state=initialState, action){
    switch (action.type){
        case FETCHING_VENDOR: return {payload:[], fetching: true}
        case FETCH_VENDOR_SUCCESS: return {payload: action.payload.data}
        case VENDOR_ERROR: return {payload:[], error: true, ...state}
    }
    return state;
}

Мой вопрос:

Я хочу сохранить этот шаблон общих / повторно используемых компонентов поставщика - я не хочу новый компонент для каждого поставщика , То же самое касается действий / редукторов; действия / редукторы уникальных поставщиков могут стать беспорядочными.

Как я могу разделить / разделить / разделить одно хранилище Redux на указанные поставщиком c порции, чтобы поддерживать разделение состояний, но при этом использовать один поток. Спасибо !!

Ответы [ 2 ]

1 голос
/ 08 февраля 2020

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

В противном случае вам потребуется встроенный редуктор:

const supportedActions = [FETCHING_VENDOR, FETCH_VENDOR_SUCCESS, VENDOR_ERROR];

const initialVendorState = {data:[], fetching: false, error: false};

const vendorReducer = (state = initialVendorState, action) => {
    switch (action.type){
        case FETCHING_VENDOR: return {data:[], fetching: true}
        case FETCH_VENDOR_SUCCESS: return {data: action.payload.data}
        case VENDOR_ERROR: return {...state, data:[], error: true}
    }
    return state;
}

const reducer = (state = {}, action) => {
  if (supportedActions.includes(action.type)) {
    const s = {};
    s[action.payload.vendor] = vendorReducer(state[action.payload.vendor], action);
    return {
      ...state,
      ...s
    };
  }

  return state
}

export default reducer;

И создатели ваших действий должны взять vendor в качестве параметра и передать его редуктору:

const fetchVendorSuccess = (vendor, data) => ({
  type: FETCH_VENDOR_SUCCESS,
  payload: {
    vendor,
    data
  }
});

В вашей функции connect вам нужно будет использовать что-то вроде data: (state[vendor] || {}).data, чтобы избежать ошибок, если состояние не есть информация об этом продавце

0 голосов
/ 09 февраля 2020

Однако, когда у меня более одного универсального c компонента Vendor, какой бы асинхронный c вызов не завершился последним, создается впечатление, что он превалирует над всеми остальными. Например, если oracle завершит последнюю загрузку, состояние компонента Microsoft изменится и покажет данные oracle.

Вы видите Oracle данные, потому что после выборки данных поставщика вы перезаписываете полное состояние поставщика с последним массивом элементов поставщика.

  case FETCH_VENDOR_SUCCESS: return {payload: action.payload.data}

Чтобы избежать этого, вам необходимо объединить предыдущее состояние с новым.

Решение зависит от того, как выглядит ответ каждого поставщика. Как предложил Геннадий, вы можете использовать объект и сделать каждого продавца свойством объекта.

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

Чтобы избежать перезаписи предыдущего поставщика, вам необходимо объединить новое состояние с предыдущим состоянием. Например,

  case FETCH_VENDOR_SUCCESS: return [...state.data, ...payload.data]
...