Разумно ли использовать «контекст» React для доступа к мутаторам модели в приложении без Flux?

Я запускаю новое приложение React и, увидев все новости в экосистеме, хочу не торопиться и действительно обдумать свой выбор, начиная только с React/Webpack/Babel и добавляя больше.

Первый из этих вариантов — использовать Flux или нет (точнее, Redux, который выглядит великолепно и, кажется, выиграл войну с потоками). Вот где я:

  1. Я понимаю преимущества Redux, резюме на SO Дэна Абрамова. Они выглядят великолепно, но я бы предпочел вводить вещи шаг за шагом.
  2. In plain React, parent→child communication is done with props, and child→parent communication happens with callbacks. See Doc / Communicate Between Components, or SO / Child to parent communication in React (JSX) without flux, or this codeacademy Redux tutorial which starts out by saying "no need for Redux if you're fine with plain React and all your data in a root component".

Чтобы решить эту проблему без введения новых зависимостей, я нашел две статьи (1: Эндрю Фармер , 2: Hao Chuan) поощряет использование недавно представленного контекстная функция React.

→ Использование context позволило бы мне открыть мои обратные вызовы, изменяющие модель, для моих дочерних компонентов. Для меня это не звучит как ужасное неправильное использование: я бы не передал данные модели, а только ссылки на функции для привязки к обработчикам событий.

  • Звучит здраво?
  • Есть ли какие-нибудь другие предложения на основе простой реакции для удобного общения между детьми и родителями?

Спасибо.


person Ronan Jouchet    schedule 02.08.2016    source источник


Ответы (2)


Отвечая на мой собственный вопрос после просмотра серии Дэна Абрамова Начало работы с Redux, которую я тепло рекомендовать.

Да, похоже, это нормально: Redux столкнулся с той же проблемой и решил ее с помощью Context (по крайней мере, изначально реализация могла измениться). Он реализован и упакован (среди прочего) в привязках react-redux под компонентом <Provider> и функцией connect().

  1. Первоначально, в начале шага 24 - Явная передача хранилища через Реквизит, у нас есть приложение Todo с хранилищем Redux, доступным как переменная верхнего уровня. Это отстой (1. тестируемость/мокабельность, 2. рендеринг сервера, требующий "разного экземпляра хранилища для каждого запроса, потому что разные запросы имеют разные данные"), поэтому хранилище понижено с переменной верхнего уровня до свойство корневого компонента.

  2. Как и в моем случае, необходимость передавать хранилище в качестве реквизита для каждого компонента раздражает, поэтому в 25 - Неявная передача хранилища через контекст. Дэн демонстрирует использование Context для передачи хранилища Redux произвольно вложенным компонентам.

  3. За ним следует 26 – Прохождение Store Down с <Provider> из react-redux, объясняя, как это было инкапсулировано в привязках react-redux.

  4. И 27 - Создание контейнеров с помощью connect() из React Redux дополнительно инкапсулирует генерацию компонента-контейнера из презентационного компонента.

person Ronan Jouchet    schedule 03.08.2016
comment
В отношении контекста важно помнить, что вы не получаете автоматический повторный рендеринг, который вы делаете с реквизитами. Если shouldComponentUpdate возвращает false где-то в вашем дереве, дочерние элементы не будут отображаться, даже если контекст изменился. Redux (а также Facebook Flux и т. д.) обходит это, обновляя «состояние» любого подключенного компонента в ответ на изменения состояния хранилища, вызывая повторное отображение «подключенного» поддерева, если это необходимо. - person TomW; 08.08.2016

Лично я считаю, что на этот вопрос довольно просто ответить, если подумать о том, как работает внедрение зависимостей в Angular. В Angular у вас есть свой DOM, а затем у вас есть все эти сервисы, провайдеры, фабрики, константы и еще много чего, которые не зависят от структуры DOM и могут быть импортированы, просто упомянув их имя при создании модулей или контроллеров.

Я сравниваю использование this.context с DI. Отличие от Angular заключается в том, что вместо указания зависимостей с использованием имен параметров функций вы используете childContextTypes и вместо того, чтобы получать зависимости в качестве аргументов функции, вы получаете их через this.context.

В этом смысле вопрос о том, разумно ли передавать мутаторы модели через this.context, сводится к тому, имеет ли смысл в Angular регистрировать вашу модель для внедрения зависимостей. Я никогда не видел проблем с последним, поэтому я делаю вывод, что с первым тоже все в порядке.

Я не говорю, что это соответствует духу библиотеки. Внедрение зависимостей и, в частности, управление зависимостями между внедренными компонентами не так явно, поэтому можно утверждать, что это не способ React. Я оставляю эту философскую дискуссию другим.

person Stefan Dragnev    schedule 19.09.2016