Мне кажется, я вижу, с чем вы боретесь. Прежде всего позвольте мне попытаться описать сценарий, с которым вы, по-моему, имеете дело более подробно.
У вас есть A
и B
в вашем магазине. C
является производным от A
и B
, поэтому, если A
изменится, вы захотите восстановить C
и положить его в свой магазин. После этого вы можете получить компонент prop E
, полученный из C
и D
. Действие x
изменяет A
, и теперь вам нужно новое значение для C
или E
, и это трудно сделать за один шаг, не усложняя редукторы.
Существует три основных подхода, которые я использовал для подобных сценариев, и какой из них я бы порекомендовал, зависит от специфики сценария. Все это просто разные подходы к тому, как / когда / где определить C
(и могут быть распространены на дальнейшие деривации, такие как E
).
Подход 1
Подсчитайте C
в промежуточном программном обеспечении, предназначенном для борьбы с побочными эффектами действий.
Этот подход наиболее похож на тот, который у вас уже есть. Он просто перемещает его из компонента, поэтому вы не боретесь с взаимодействием между вашим магазином и тем, как методы жизненного цикла получают новую информацию. Для этого подхода я бы использовал Redux Saga, чтобы он обрабатывал C
в ответ на действие x
и отправлял действие, чтобы обновить магазин с новым значением для C
. Это легко сделать (если вы прошли начальную кривую обучения Redux Saga), поскольку Redux Saga получает действие после того, как магазин уже обновлен. Основным недостатком этого подхода является то, что ваш магазин будет временно находиться в несогласованном состоянии, где C
еще не отражает изменение на A
. Для некоторых сценариев это важно, а для некоторых - нет. Другим потенциальным недостатком является то, что, если вы еще не используете Redux Saga, сначала это может быть немного пугающим, потому что использование функций генератора и yield
и весь склад ума при использовании Redux Saga может показаться немного чуждым (но я очень люблю использовать Redux Saga для сложных асинхронных сценариев).
Подход 2 Рассчитать C
в создателе действий.
Обычно это включает использование thunk для первоначального ответа на действие x
, после чего thunk может получить B
из хранилища, вычислить C
и отправить действие с полезной нагрузкой, которая содержит две части - одна использованная редуктором для A
и одним редуктором для C
. Основным недостатком этого подхода является то, что если существует несколько способов изменения зависимостей для C
(то есть A
и B
), это может стать сложным способом организации вещей, но для некоторых сценариев он может работать нормально , В основном я отошел от этого подхода в пользу двух других.
Подход 3 Не кладите C
в свой магазин.
Если C
полностью получен из других вещей в вашем магазине, то в действительности он не должен быть в магазине. C
- это просто просмотр другой информации в вашем магазине. Вместо этого вы можете использовать селектор для этой цели. Если вывести C
дорого, используйте запомненный селектор. В более сложном случае наличия E
, полученного из C
и D
, селектор для E
может использовать селектор для C
при получении D
из магазина. Этот подход я обычно одобряю, если нет веских причин для C
в магазине. Такой подход позволяет вашим редукторам оставаться простыми и независимыми, сохраняя ваш магазин в согласованном состоянии.
Другие подходы
Есть и другие способы сделать это, но 3 подхода, описанных выше, я использовал сам. Еще один способ - использовать редуктор, который использует другие редукторы. В этом подходе редукторы для A
и B
будут использоваться редуктором, который затем вычисляет C
и возвращает состояние со всеми тремя частями информации. Существуют пакеты для облегчения составления редукторов таким образом, но я не использовал их, потому что меня не очень интересует этот подход. Для меня это просто неправильное место, чтобы описать эту сложность.