Разделительные редукторы, работающие с одним и тем же срезом данных в Redux - PullRequest
0 голосов
/ 04 декабря 2018

У меня есть магазин, который имеет такую ​​форму:

{
  // ...data

  user: {
    warranties: {
      W_1: ['O_1', 'O_2'],
      W_2: ['O_3', 'O_4']   
    }
  }
}

Где ключи, начинающиеся с W_, являются гарантиями, ключи, начинающиеся с O_, являются вариантами.

Для каждого гарантия У меня есть один или несколько вариантов , связанных с ним, отношения в user.warranties имеют вид: warranty => [options].

Для достижения этого я объединяю своиредукторы, подобные этому:

rootReducer = combineReducers({
  // ...other main reducers

  user: combineReducers({
    // ...other user reducers
    warranties
  })
})

Теперь " проблема " заключается в том, что действия USER_WARRANTY и USER_OPTION обрабатываются одним и тем же редуктором, потому что:

  • Когда я добавляю опцию, мне нужно нажать ее для правильного ввода гарантии.

  • Обратно, когда я добавляю гарантию, мне нужно заполнить еес параметрами по умолчанию.

  • И, в конечном итоге, они работают с одним и тем же фрагментом данных

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

export default function warranties(state = {}, action) {
  switch (action.type) {
    case USER_WARRANTIES_ADD:
    // add warranty key to `user.warranties`

    case USER_WARRANTIES_REMOVE:
    // remove warranty key from `user.warranties`

    case USER_OPTIONS_ADD:
    // push option to `user.warranties[warrantyID]`

    case USER_OPTIONS_REMOVE:
    // remove option from `user.warranties[warrantyID]`

    default:
      return state
  }
}

Я хотел бы разделить это на два редуктора, warranties и options, но все же заставить их работать на том жекусок данных.

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

rootReducer = combineReducers({
  // ...other main reducers

  user: combineReducers({
    // ...other user reducers
    warranties: magicalCombine({
      warranties,
      options
    })
  })
})

Где magicalCombine - это функция, которую я не могу найти.


Я пытался reduce-reducers, но похоже, что второй редуктор (options) фактически никогда не достигается, и я на самом деле не уверен в этом, так как я не пытаюсь достичь плоского состояния, но на самом деле работают с тем же ключом.

1 Ответ

0 голосов
/ 05 декабря 2018

Редуктор - это простая функция, которая принимает state и action и возвращает новый объект состояния, поэтому я думаю, что это будет делать то, что вы хотите.

rootReducer = combineReducers({
  // ...other main reducers

  user: combineReducers({
    // ...other user reducers
    warranties: (state, action) => {
      // state is state.user.warranties
      // we pass it to each reducer in turn and return the result
      state = warranties(state, action);
      return options(state, action);
    }
  })
})

с использованием reduReducers должно сделатьто же самое (я не использовал это раньше, но это то, на что это похоже ..)

rootReducer = combineReducers({
  // ...other main reducers

  user: combineReducers({
    // ...other user reducers
    warranties: reduceReducers(warranties, options)
  })
})

combineReducers от redux просто намеренно ограничено, чтобы передавать только значение свойства состояния, которое соответствуетвведите предоставленный ему объект-редуктор, это не совсем особенный способ.подробнее здесь .. https://redux.js.org/recipes/structuringreducers/beyondcombinereducers

...