По мере того, как я продвигаюсь в реализацию redux +, реагирую на довольно сложное приложение, которое зависит от многих запросов API для загрузки одной страницы, у меня возникают проблемы с решением, нужно ли иметь один контейнерный компонент в корне страницы который обрабатывает все асинхронные вещи и передает реквизиты до немых компонентов, vs имеющих несколько компонентов контейнера, которые относятся только к необходимым им данным, а также к сбору данных, которые им нужны. Я пошел туда и обратно между этими двумя шаблонами и обнаружил, что у каждого из них есть плюсы и минусы:
Если я поставлю один компонент контейнера вверху:
- pro: Все действия
isFetching
реквизита иfetchSomeDependency()
могут обрабатываться в одном месте. - con: недостаток, который действительно раздражает, заключается в том, что мне приходится пересылать реквизиты и обратные вызовы через несколько компонентов, а некоторые компоненты в середине дерева в конечном итоге привязаны к этому.
Здесь наглядный пример проблемы, которая показывает отношения, требуемые реквизитом:
<MyContainer
data={this.props.data}
isFetchingData={this.props.isFetchingData}
fetchData={this.props.fetchData}
>
{!isFetchingData &&
<MyModal
someData={props.data}
fetchData={props.fetchData}
>
<MyModalContent
someData={props.data}
fetchData={props.fetchData}
>
<SomethingThatDependsOnData someData={props.someData} />
<SomeButtonThatFetchesData onClick={props.fetchData} />
</MyModalContent>
</MyModal>
}
</MyContainer>
Как вы можете видеть, <MyModal />
и <MyModalContent />
теперь нужно иметь дело с реквизитами, которые не имеют к этому никакого отношения, поскольку модальность должна быть в состоянии повторно использоваться и учитывать только стилистические качества модальный.
Вначале это выглядело здорово, но как только я добрался до более 100 компонентов, все это было очень запутанным, и я обнаружил, что сложность этих компонентов контейнера верхнего уровня слишком высока по моему вкусу, поскольку большинство из них (в приложение, над которым я работаю) зависят от ответов от запросов API 3+.
Затем я решил попробовать несколько контейнеров:
- pro: Полностью устраняет необходимость перенаправления реквизита. В некоторых случаях это имеет смысл сделать, но это намного более гибко.
- pro: Упрощение рефакторинга. Я удивлен тем, как я могу значительно перемещаться и реорганизовать компоненты без каких-либо взломов, тогда как в другом шаблоне все ломается много.
- pro: Сложность каждого компонента контейнера намного меньше. Мои
mapStateToProps
иmapDispatchToProps
более специфичны для цели компонента, в котором он находится. - con: Любой компонент, зависящий от материала async, всегда должен обрабатывать состояние
isFetching
сам по себе. Это добавляет сложности, которые не нужны в шаблоне, где его обрабатывают в одном компоненте контейнера.
Таким образом, главная проблема заключается в том, что если я использую один контейнер, я получаю эту ненужную сложность в компонентах между корневым контейнером и компонентами листа. Если я использую несколько контейнеров, я получаю больше сложностей в компонентах листа и получаю кнопки, которые должны беспокоиться о isFetching
, хотя кнопка не должна беспокоиться об этом.
Я хотел бы знать, нашел ли кто-нибудь способ обойти оба недостатка, и если да, то каково "правило большого пальца", которое вы следуете, чтобы избежать этого?
Спасибо!