React-Redux: куда я могу поместить побочный эффект, который использует часть редуктора? - PullRequest
0 голосов
/ 29 апреля 2020

Я не знаю побочных эффектов в редукторах, и я знаю, что есть много хороших объяснений о том, как обрабатывать асин c действия. Я прочитал их. У меня есть конкретный вопрос, на который я поставлен. Спасибо!

У меня есть state.largeObject, который является объектом со многими записями. У меня есть редуктор, который делает некоторые сложные логики c и объединяет результат в state.largeObject примерно так:

export const myReducer = (state, { input }) => {
  const largeObject = doSomethingComplex(input)
  // other logic that uses largeObject

  return {
    ...state,
    largeObject: {
      ...state.largeObject,
      ...largeObject
    }
  }
}

Я хочу сохранить результат doSomethingComplex(input) на сервере. Куда положить побочный эффект? РЕДАКТИРОВАТЬ: без дублирования doSomethingComplex, который по-прежнему необходим для других логи c в редукторе.

  • Я не могу поместить это в myReducer или doSomethingComplex, так как они чисты.
  • Я не могу поместить его в промежуточное ПО Redux, поскольку оно имеет доступ только к действию и состоянию в целом. Я не хочу вызывать doSomethingComplex как в редукторе, так и в промежуточном программном обеспечении.
  • Я не хочу превращать его в создателя действий, так как это заставит много чистой функциональности в спасибо, что затрудняет сочинение.

Чего мне не хватает? Спасибо!

Ответы [ 2 ]

1 голос
/ 29 апреля 2020

Наиболее подходящим подходом, на мой взгляд, было бы перемещение всего редуктора logi c (ваша doSomethingComplex функция) на сторону сервера.

Итак, все, что вам нужно сделать, - это отправить действие и отправить необходимые аргументы в API. В случае успешного ответа вы отправите действие success , позвоните myReducer и сохраните результат в магазине.

Однако , если вы действительно Если вы хотите сохранить эту логику c на лицевой стороне, вам придется использовать промежуточное ПО - thunks или sagas (я предпочитаю sagas).

// some pseudo code //

dispatch the action
- inside the middleware - 
  call doSomethingComplex() // called once and stored in some variable
  dispatch action that will call the reducer and store the result
  call API with the result

Но все же я бы рекомендовал первое решение, так как этот (второй) подход будет работать, но может нарушить надлежащий поток данных.

Редактировать : несколько заключительных мыслей - если вы действительно хотите сохранить эти вычисления на внешней стороне, рассмотрите следующую стратегию:

  • отправьте действие
  • внутри промежуточного ПО (thunks или sagas) вызов doSomethingComplex функция
  • вызов API с stuff , который doSomethingComplex вернул
  • return материал - который doSomethingComplex возвратил - от API как success ответ
  • действие вызова успешно с stuff и вызовите редуктор, который сохранит его в хранилище

Вот так можно поддерживать правильный поток данных.

1 голос
/ 29 апреля 2020

Промежуточное программное обеспечение, групповые вызовы и обратные вызовы по подписке для магазинов - все допустимые места для этого:

  • Хорошо иметь некоторые логики сохранения c как часть группы. Thunks - это тип промежуточного программного обеспечения, и именно здесь побочные эффекты должны существовать в целом.
  • У вас может быть пользовательское промежуточное программное обеспечение, которое ищет определенный тип действия c, который приводит к этому изменению, или проверяет посмотрим, изменился ли этот кусок состояния, и сделает ли он вызов на сервер после того, как состояние было обновлено
  • Вы могли бы иметь обратный вызов подписки магазина, который проверяет, изменился ли этот кусок состояния, и выполняет вызов на сервер

Исходя из того, как вы сформулировали, я не уверен, что вы хотите отправить только результат этого вызова на сервер или результат выполнения {...state.largeObject, ...largeObject}.

...