Зачем нужен redux?
Что нам дает редукс архитектура (НИКАКОГО РЕАКТА. ) в сравнении с любой паб/саб библиотекой? Как вообще использовать редукс в ванилла+jquery-плагины проекте?
Подобається Сподобалось 0
До обраного В обраному 0
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
14 коментарів
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Что творится с ДОУ? Куда смотрит модератор? Какая-то совсем левая тема .
Dmytro Shchurov Frontend/React Developer в KAJO s.r.o. 29.11.2017 14:32
Не забывайте про middleware. Начиная от логгеров и заканчивая saga
Redux это либа в которой:
- есть один объект
- есть 2 метода, которые дают возможность его инициализировать и получить
- 1 метод, который дает возможность его поменять
- subscribe/observable, который дает возможность оповещать об изменениях
- и всякие мелочи для удобства
Mark Donia Senior Software Engineer 29.06.2020 21:49
Ну все таки redux хранит стейт в себе, и флакс вроде как подразумевает свой паттерн биндинга этого стейта и UI.
Почитаю еще флакс. Может пойму что-то новое для себя. И все равно все твердят mvc на клиенте умерло — да здраствует редукс. Отсюда возникает вопрос как этот редукс использовать на примере допустим www.jstree.com ? Скажем я добавил ноду к дереву. Не убивать же мне весь плагин и пересоздавать заново из состояния только из-за того что у меня добавился один узел к плагину?
Ну это уже надо вникать в логику приложения, как ноду добавлешь и т.п.
В принципе можешь отлавливать апдейт реактовского компонента(который происходит из-за изменения стейта в redux) и из него делать с плагином то что хочется.
В общем в реакте все стараются юзать реактовые либы, и вообще там jQuery это антипаттерн.
А по поводу MVC, то там все от контекста беседы зависит, уж слишком много у него сейчас трактовок и вариаций.
В общем в реакте все стараются юзать реактовые либы, и вообще там jQuery это антипаттерн.
В этом и дело. Redux заявлен как библиотека-архитектура, не имеющая ничего общего общего с реактом, ангуларом или еще чем либо. Кто-то может подтвердить, что редукс без виртуального дома не имеет смысла? Мне почему-то пока кажется, что так и есть.
Redux is a predictable state container for JavaScript apps.
Почему нет, используй subscribe, произошел state update — запускай rerender нужного компонента .
Вся суть react-redux в подписках на state и обновления Provider-а ну и прочие плюшки )
github.com/. s/connectAdvanced.js#L194
Редакс — это модель. Где и как хранить данные, как их обновлять, чтобы было удобненько и не было размазано по всему приложению. Виртуальный дом — это про вью, как отрендерить-перерендерить быстрее и эффективнее. Это совершенно независимые вещи.
Виртуальный дом — это про вью, как отрендерить-перерендерить быстрее и эффективнее. Это совершенно независимые вещи.
Верно. Так и было заявлено создателями.
Допустим у меня есть www.jstree.com и его нужно перерендеривать из данных из стора полностью после каждого добавления/удаления всего лишь одной ноды? Это неэффективно без вирутального дома. Эффективно было бы у плагина вызвать методы addNode/removeNode. Но откуда мне в сабскрайбе узнать что именно произошло удаление добавление либо это первый вызов плагина для инициализации.
Podoprigora Alexandr front-end developer в freelace 29.11.2017 18:28
Вы пытаетесь продублировать функциональность компонента с помощью Redux (непонятно только зачем так сильно усложнять себе жизнь).
Используйте MVC, если нет четкого понимания как эффективно использовать Redux (medium.com/. t-need-redux-be46360cf367). Использование любого инструмента должно быть оправдано, например: увеличение производительности, масштабируемости, и т.д. Если просто интересно, потратьте неделю-две на изучение документации и примеров redux.js.org тогда будет понимание зачем ))
Руководство по Redux для начинающих
Redux — популярный менеджер состояний в веб-приложениях. Обычно его используют в связке с React, но поддержка не ограничена только этой популярной JS-библиотекой. Можно применять Redux вместе с Angular, Vue и даже ванильным JavaScript.
Професійний курс від robotdreams: Алгоритми та структури даних.
Знаходьте нестандартні рішення у складних робочих задачах.
Redux появился в 2015 году в ответ на экспоненциальный рост сложности интерфейсных приложений. Он объединил подход Flux (однонаправленный поток данных со специфическими событиями и слушателями) с функциональным программированием и за короткий срок превратился в одну их самых популярных интерфейсных архитектур.
Предназначение Redux — управление состоянием приложений. В основе библиотеки лежат несколько концепций, которые вы изучите в этом руководстве для начинающих.
Професійний курс від skvot: PR basis.
Засвоєте основи PR та комунікації.
1. Когда нужно пользоваться Redux
В простых проектах Redux не нужен. Но если в приложении несколько компонентов, которым необходимо совместно использовать одно и то же состояние, при этом сами компоненты расположены в разных частях приложения, то без Redux управлять состоянием будет сложно.
Еще одна мотивация использовать Redux — замена стандартных механизмов локального хранилища. Например, в React хранилище изолировано. Если нужно передавать состояние между компонентами, то приходится использовать пропсы либо поднимать его наверх до ближайшего «родителя». Redux устраняет эту проблему.
2. Основные концепции
Основная идея Redux — создать централизованное место для хранения глобального состояния приложения. Для достижения этой цели используются три основные концепции.
Единственный источник состояния
Глобальное состояние приложения ( state ) хранится в виде объекта внутри одного хранилища ( store ). Любой фрагмент данных в момент может существовать только в одном месте и не может дублироваться в других местах.
Такой подход упрощает отладку и проверку состояния приложения по мере его изменения, а также централизует логику, которая взаимодействует со всем приложением.
Состояние приложения содержится в хранилище. Отобразить его можно вызовом функции getState() . Для обновления используется функция dispatch() . Зарегистрироваться в качестве слушателя состояния или удалиться помогает функция subscribe() .
Хранилище всегда уникально. Вот пример его реализации:
import < createStore >from 'redux' import listManager from './reducers' let store = createStore(listManager)
Можно также инициировать хранилище через серверные данные:
let store = createStore(listManager, preexistingState)
Примеры применения функций:
Ефективний курс від skvot: Режисура відеороликів.
Творча магія кінематографу.
store.getState() // Получаем состояние store.dispatch(addItem('Something')) // Обновляем состояние const unsubscribe = store.subscribe(() => const newState = store.getState() ) unsubscribe() // Слушаем изменения состояния
Состояние доступно только для чтения
Общее состояние приложения представлено объектом JS. Неизменяемое дерево состояний доступно исключительно для чтения. Единственный способ внести изменения — отправить action (действие), объект JS, который описывает, что произошло.
Благодаря такому подходу пользовательский интерфейс не перезаписывает данные случайно. Разработчику проще отследить, почему состояние обновилось. Поскольку действия являются объектами JS, их можно регистрировать, сериализировать, сохранять и воспроизводить для отладки и тестирования.
< type: 'CLICKED_LINK' >// подробности об изменении
Единственное требование к action — добавление свойства type , значением которого обычно является строка. По мере разрастания приложений строки в типах действий заменяют константами, а затем выносят в отдельные файлы и импортируют. Это упрощает внесение изменений и дальнейшее масштабирование проекта.
Например, так могут выглядеть константы:
const ADD_DATA = ‘ADD_DATA’ const action =
Затем эти константы можно импортировать в другой файл:
import < ADD_DATA, UPDATE_DATA >from './actions'
Создавать действия помогают функции-генераторы.
function adddata(some) < return < type: ADD_DATA, title: some >>
Обычно они инициируются вместе с dispatch — функцией отправки действия.
dispatch(adddata('Highload'))
Но можно инициировать их и при определении функции отправки:
Освітній курс від laba: Delivery Manager.
Ведіть проекти до успішної доставки.
const dispatchAdddata = i => dispatch(adddata(i)) dispatchAdddata('Highload')
Изменения вносятся только через редукторы
Когда вы отправляете action , что-то случается и состояние приложения меняется. За эту часть работы отвечают редукторы.
Редуктор ( reducer ) — чистая функция, которая берет предыдущее состояние и переданное действие, а затем на их основе вычисляет новое состояние. Как и любые другие функции, редукторы можно разбивать на более мелкие или делать переиспользуемыми.
Редуктор НЕ должен менять аргументы и само состояние. Он каждый раз создает новое состояние. Работа чистой функции также не должна вызывать побочных эффектов и вызова нечистых функций — тех, результат которых зависит от чего-то еще, кроме их аргументов.
Чем сложнее приложение, тем больше редукторов может применяться к одному действию.
3. Базовая структура Redux
Используя основные концепции Redux, можно представить такую базовую структуру:
< list: [ < title: "First" >, < title: "Second" >, ], title: 'List' >
Редуктор для каждой части состояния:
const title = (state = '', action) => < if (action.type === 'CHANGE_LIST_TITLE') < return action.title >else < return state >> const list = (state = [], action) => < switch (action.type) < case 'ADD_DATA': return state.concat([< title: action.title >]) case 'REMOVE_DATA': return state.map((item, index) => action.index === index ? < title: item.title >: item default: return state > >
Редуктор для общего состояния:
const listManager = (state = <>, action) => < return < title: title(state.title, action), list: list(state.list, action), >>
4. Поток данных
Чтобы лучше понимать, как работает поток данных в Redux, возьмем простой пример компонента React. Пусть это будет счетчик, который отслеживает число и увеличивает его при нажатии на кнопку.
function Counter() < const [counter, setCounter] = useState(0) const increment = () => < setCounter(prevCounter =>prevCounter + 1) > return (Value:) >
Приложение состоит из трех частей:
- State — источник состояния, который управляет приложением.
- View — декларативное описание интерфейса на основе текущего состояния.
- Action — события, которые происходят в приложении после пользовательского ввода и инициируют изменение состояния.
В Redux используется односторонний поток данных — наследство подхода Flux. Пошагово его можно описать следующим образом:
- Состояние описывает приложение в текущий момент времени.
- На основе состояния отображается пользовательский интерфейс.
- Когда происходит действие, состояние обновляется.
- Пользовательский интерфейс отображает обновленное состояние.
Простой пример со счетчиком и кнопкой. Счетчик показывает 0 — это текущее состояние, которое отображается в интерфейсе. Пользователь нажал на кнопку и таким образом отправил действие. Состояние изменилось — с 0 на 1. Теперь в интерфейсе отображается обновленное состояние: счетчик показывает 1.
Для Redux этот же пример можно описать более подробно. Так происходит начальная настройка состояния:
- Хранилище создается с использованием корневого редуктора.
- Хранилище вызывает корневой редуктор и сохраняет возвращенное значение как начальное.
- При первом отображении пользовательского интерфейса его компоненты получают доступ к текущему состоянию. Они используют эти данные, чтобы понять, что показать пользователю. В то же время компоненты подписываются на все будущие изменения, чтобы вовремя их обнаружить и отобразить.
А вот как проходят все изменения состояния:
- В приложении что-то происходит — например, пользователь нажимает кнопку.
- Приложение отправляет action в хранилище Redux с помощью функции dispatch() .
- Хранилище запускает функцию редуктора с предыдущим состоянием и полученным действием. Возвращаемое значение хранилище сохраняет как новое состояние.
- Хранилище уведомляет все подписанные на изменения части пользовательского интерфейса о новом состоянии.
- Каждый компонент проверяет, не изменились ли нужные ему части.
- Каждый компонент, которому нужны измененные части, вызывает повторную отрисовку с новыми данными, чтобы отобразить их на экране.
Несмотря на такое пространное описание, концепция однонаправленного потока данных проста. Все действия передаются через dispatch() в хранилище, где редуктор генерирует новое состояние. Затем хранилище уведомляет всех слушателей. И так по кругу.
5. Установка и начало работы
Установить Redux можно через NPM или YARN:
npm install redux yarn add redux
Redux не знает, как вы структурируете приложение. Есть несколько популярных шаблонов. Но на старте лучше выбрать один подход и придерживаться его, пока не разберетесь до конца, как части приложения взаимодействуют друг с другом.
Для обучения можно использовать самую простую структуру — создать папку store и поместить внутри нее все, что связано с Redux и хранилищем. Пример такой структуры:
.store ├── actionCreators │ ├── action_1.js │ └── action_2.js ├── actions │ ├── action_1.js │ └── action_2.js ├── reducers │ ├── reducer_1.js │ ├── reducer_2.js │ └── rootReducer.js ├── initialState.js └── store.js
Один из самых распространенных шаблонов — структура в стиле Rails. В ней используется несколько каталогов верхнего уровня. Например, такой может быть структура для проекта на React + Redux:
- Components — для хранения компонентов React. Здесь не нужна связь с Redux.
- Containers — папка с компонентами Smart React, которые отправляют действия в Redux. Здесь настраивается связь React и Redux.
- Actions — каталог с генераторами действий.
- Reducers — папка с отдельными файлами для каждого редуктора.
- Store — каталог с настройками хранилища и логикой инициализации состояния.
Этот шаблон подходит для приложений небольшого и среднего размера. На больших проектах может быть удобнее использовать стиль домена или аналогичный. В таком случае у каждой функции будет свой каталог (домен), внутри которого будет храниться все, связанное с этой функцией.
Заключение
В этом руководстве вы познакомились с Redux и изучили его основные концепции. Чтобы закрепить знания, посмотрите эти курсы на русском и английском языках:
Что делает Redux? (и когда его следует использовать)
Ломаете голову с Redux? Не беспокойтесь, вы не одиноки.
Я слышал от множества людей, что Redux — самое большое препятствие при написании приложений React.
К концу этого сообщения вы поймете, для чего нужен Redux, и как узнать, когда пришло время добавить его в свое приложение.
Зачем?
Лучший вопрос для начала: зачем нам вообще Redux?
И ответ отнюдь не «потому что все остальные в Интернете используют его». (Я не сомневаюсь, что многие используют его, но давайте заглянем поглубже.)
Причина, по которой Redux полезен, заключается в том, что он решает проблему.
И нет, проблема, которую он решает, — это не «управление состоянием». Это очень расплывчатый ответ. React уже занимается управлением. Да, Redux помогает управлять состоянием, но это не проблема, которую он решает.
Поток данных
Если вы использовали React более нескольких минут, тогда, вероятно, знаете о реквизитах и одностороннем потоке данных. Данные передаются по дереву компонентов через реквизиты. Учитывая такой компонент:
count, хранящийся в состоянии App, будет передана в качестве prop:
Для данных, чтобы вернуться на дерево, она должна проходить через функцию обратного вызова, так что функция обратного вызова должна быть передана вниз любым компонентам, которые хотят передать данные вверх.
Вы можете думать о данных по аналогии с электричеством, связанном цветными проводами с компонентами. Данные проходят вниз и вверх по этим проводам, но провода не могут проходить через тонкий воздух — они должны быть связаны между каждым компонентом в дереве.
Надеемся, это понятно. (Если нет, вы должны остановиться, пойти учиться React, создать пару небольших приложений и вернуться через несколько дней. Серьезно. Redux не имеет смысла, пока вы не поймете, как работает React).
Слои (потока данных)
Рано или поздно вы сталкиваетесь с ситуацией, когда в контейнере верхнего уровня есть некоторые данные, а для 4 уровня нужны эти данные. Вот скриншот Twitter, со всеми аватарами:
Предположим, что аватар пользователя хранится как часть данных профиля, а компонент App верхнего уровня содержит пользователя. Чтобы доставлять пользовательские данные ко всем 3 компонентам Avatar, user необходимо провести через кучу промежуточных компонентов, которые не нуждаются в данных.
Это не очень хороший дизайн для программного обеспечения. Промежуточные компоненты в цепочке должны принимать и проходить по props, которые не нужны. Это означает, что рефакторинг и повторное использование компонентов из этой сети будет сложнее, чем нужно.
Было бы неплохо, если бы компоненты, которые не нуждались в данных, не должны были видеть это вообще?
Подключить любые данные к любому компоненту
Это проблема, которую решает Redux. Он предоставляет компонентам прямой доступ к требуемым данным.
Используя функцию connect, которая поставляется с Redux, вы можете подключить любой компонент к хранилищу данных Redux, а компонент может вытащить нужные ему данные.
Это реальность Redux.
Да, это также облегчает отладку (Redux DevTools позволяет вам проверять каждое изменение состояния), вы можете откатывать изменения состояния и видеть, как ваше приложение выглядело в прошлом. Это также позволяет сделать код более удобным для обслуживания в долгосрочной перспективе. Это научит функциональному программированию.
Но эта вещь здесь, «подключить любые данные к любому компоненту», является основным событием. Если вам это не нужно, вам, вероятно, не нужен Redux.
Компонент Avatar
Чтобы связать все это с кодом, вот пример компонента Avatar:
import < connect >from 'react-redux'; const Avatar = (< user >) => (
/> ); const mapStateToProps = state => (< user: state.user >); export < Avatar >; export default connect(mapStateToProps)(Avatar);
Сам компонент не знает о Redux — он просто принимает user prop и отображает изображение аватара. Функция mapStateToProps извлекает user из магазина Redux и отображает его на user prop. Наконец, функция connect — это то, что фактически передает данные из Redux через mapStateToProps и в Avatar.
Вы заметите, что есть два export с конца — именованный, и по умолчанию. Это не строгая необходимость, но может быть полезно получить доступ к необработанному компоненту и его версии, завершенной Redux.
Необработанный компонент полезен при написании модульных тестов, а также может увеличивать повторное использование. Например, часть приложения может захотеть отобразить Avatar для другого пользователя, кроме пользователя с подписью. В этом случае вы можете сделать еще один шаг и экспортировать версию, связанную с Redux, CurrentUserAvatar — чтобы сделать код более понятным.
Когда добавлять Redux
Если у вас есть компонентная структура, подобная той, что указана выше, — где реквизит пересылается вниз по многим слоям — подумайте об использовании Redux.
Если вам нужно кэшировать данные между представлениями, например, загружать данные, когда пользователь нажимает на страницу подробностей, и запоминать данные, чтобы следующий доступ был быстрым — подумайте о сохранении этих данных в Redux.
Если ваше приложение будет поддерживть обширные данные, связанные или нет — используйте Redux. Но также рассмотрите возможность запуска без него и добавьте его, когда столкнетесь с ситуацией, когда это поможет.
Что дальше
Прочтите часть 2 этой серии, где мы погрузимся в детали Redux: как его настроить и как важные элементы подходят друг другу.
С какой целью использовать React Redux?
Redux является независимой библиотекой, которая может использоваться с любой UI логикой или с любым фреймворком, включая React, Angular, Vue, Ember и vanilla JS. Несмотря на частое использование Redux и React вместе, они независимы.
Использование Redux с любым фреймворком обычно включает библиотеку «UI привязки» для связи между Redux и этим фреймворком, нежели прямое взаимодействие с Redux хранилищем (store) из UI кода.
React Redux — это официальная библиотека привязки Redux к React. Если вы используете Redux и React вместе, мы рекомендуем рассмотреть React Redux для их связи.
Причины использовать React Redux исходят из понимания работы «библиотеки привязки UI».
Если вы задаётесь вопросом касательно использования Redux в общем, пожалуйста, прочитайте указанные ниже статьи. Их понимание необходимо для дискуссии о том, когда и почему вы можете захотеть использовать Redux и как конкретно его использовать:
- Документация Redux: мотивация
- Документация Redux: FAQ — Когда стоит использовать Redux?
- Возможно, вам не нужен Redux
- Идиоматичный Redux: Дао Redux’а, Часть 1 — Реализация и Замысел
Внедряем Redux в UI
- Создать Redux хранилище (store)
- Подписаться на обновления
- Внутри колбэка подписки:
- Получить текущее состояние (state) хранилища (store)
- Извлечь используемые в этой части UI данные
- Обновить UI с извлечёнными данными
Эту логику можно написать вручную, однако тогда код будет повторяться. Вдобавок, оптимизация производительности потребует более сложной логики.
Процесс подписки на хранилище (store), проверки на наличие обновленных данных и запуска перерисовки UI может быть более шаблонным и переиспользуемым. Библиотека привязки UI как React Redux обрабатывает логику взаимодействия с Redux хранилищем (store), поэтому при её использовании вам не придётся писать этот код самостоятельно.
Для глубокого погружения во внутреннее устройство библиотеки React Redux, обработку взаимодействия с хранилищем (store), прочитайте «Идиоматика Redux: История и Имплементация React Redux».
Причины использовать React Redux
Это официальная библиотека привязки Redux к React
Несмотря на то, что Redux может быть использован с любой UI логикой, изначально он был спроектирован для использования с React. Существуют библиотеки привязки UI для многих других фреймворков, но React Redux поддерживается напрямую командой Redux.
Будучи официальной библиотекой привязки Redux к React, React Redux следит за всеми изменениями обоих библиотек для гарантии того, что ваши React компоненты будут вести себя так, как ожидалось. Использование React Redux будет соответствует принципу дизайна React — написание декларативных компонентов.
Оптимизация производительность
React в целом быстрый, но по умолчанию любые изменения в компонентах будут вызывать перерисовку во всех дочерних компонентах. Если используемые компонентом данные не изменились, эта работа будет выполнена впустую, поскольку UI на выходе будет одним и тем же.
Если вас волнует быстродействие, то лучший путь для улучшения производительности — это пропустить ненужные перерисовки, т.е. перерисовывались компоненты исключительно при изменении данных, которые они используют. React Redux реализует множество оптимизаций производительности, таким образом ваши компоненты будут перезагружаться только при необходимости.
Кроме того, путем соединения нескольких компонентов вашего дерева компонентов React, вы можете убедиться, что каждый соединённый компонент извлекает конкретные фрагменты данных из состояния Redux хранилища (store). Это значит, что вашим компонентам будет необходимо перерисовываться реже, потому что большую часть времени конкретные фрагменты не будут меняться.
Поддержка сообщества
Будучи официальной библиотекой связки Redux к React, React Redux имеет большое сообщество пользователей. Это упрощает поиск помощи, изучение лучших практик, использование библиотек, сделанных поверх React Redux и переиспользовать знания в различных приложениях.
Ссылки и рекомендации
Понимание React Redux
- Идиоматика Redux: История и Имплементация React Redux
- Объяснение connect.js
- Слайды семинара «Redux Fundamentals»
- UI слой интеграции
- Использование React Redux
Ссылки на сообщества
- Канал в Discord: #redux на Reactiflux (Reactiflux)
- Stack Overflow обсуждения: Redux, React Redux
- Reddit: /r/reactjs, /r/reduxjs
- GitHub issues (отчёты об ошибках и просьбы добавить функции): https://github.com/reduxjs/react-redux/issues
- Руководства, статьи и дальнейшие ресурсы: React/Redux Links