Поток данных
Архитектура Redux основана на строго однонаправленном потоке данных.
Это означает, что все данные в приложении следуют одному и тому же жизненному циклу, что делает логику вашего приложения более предсказуемой и понятной. Это также поощряет нормализацию данных, чтобы у вас не было нескольких независимых копий одних и тех же данных, которые не осведомлены друг о друге.
Если вы все еще не уверены, прочтите Мотивацию и Случай за Flux для убедительного аргумента в пользу однонаправленного потока данных. Несмотря на то, что Redux не является точной копией Flux, он разделяет те же ключевые преимущества.
Жизненный цикл данных в любом приложении Redux проходит следующие 4 этапа:
-
Вы вызываете
store.dispatch(action).Действие — это обычный объект, описывающий произошедшее событие. Например:
{ type: 'LIKE_ARTICLE', articleId: 42 } { type: 'FETCH_USER_SUCCESS', response: { id: 3, name: 'Mary' } } { type: 'ADD_TODO', text: 'Read the Redux docs.' }Представьте действие как очень краткий новостной фрагмент. «Мария понравилась статья 42» или ««Прочитать документацию Redux» добавлено в список задач».
Вы можете вызвать
store.dispatch(action)из любой точки вашего приложения, включая компоненты и обратные вызовы XHR, или даже по расписанию. -
Хранилище Redux вызывает функцию редуктора, которую вы ему предоставили.
Хранилище (store) передаст два аргумента редуктору: текущее состояние и действие. Например, в приложении с задачами корневой редуктор может получить что-то вроде этого:
// The current application state (list of todos and chosen filter) let previousState = { visibleTodoFilter: 'SHOW_ALL', todos: [ { text: 'Read the docs.', complete: false } ] } // The action being performed (adding a todo) let action = { type: 'ADD_TODO', text: 'Understand the flow.' } // Your reducer returns the next application state let nextState = todoApp(previousState, action)Обратите внимание, что редуктор — это чистая функция. Он только вычисляет следующее состояние. Он должен быть полностью предсказуемым: вызов его с одними и теми же входными данными много раз должен давать одинаковые результаты. Он не должен производить побочные эффекты, такие как запросы к API или переходы маршрутизатора. Это должно происходить до отправки действия.
-
Корневой редуктор может объединить выходные данные нескольких редукторов в единое дерево состояния.
Как вы структурируете корневой редуктор, зависит только от вас. Redux поставляется с
combineReducers()вспомогательной функцией, полезной для «разбиения» корневого редуктора на отдельные функции, которые каждая управляет одной ветвью дерева состояния.Вот как работает
combineReducers(). Предположим, у вас есть два редуктора: один для списка задач и другой для текущих настроек фильтра:function todos(state = [], action) { // Somehow calculate it... return nextState } function visibleTodoFilter(state = 'SHOW_ALL', action) { // Somehow calculate it... return nextState } let todoApp = combineReducers({ todos, visibleTodoFilter })Когда вы отправляете действие,
todoAppвозвращаемыйcombineReducersвызовет оба редуктора:let nextTodos = todos(state.todos, action) let nextVisibleTodoFilter = visibleTodoFilter(state.visibleTodoFilter, action)
Затем он объединит оба набора результатов в одно дерево состояния:
return { todos: nextTodos, visibleTodoFilter: nextVisibleTodoFilter }Хотя
combineReducers()и есть удобная вспомогательная функция, вы не обязаны ее использовать; чувствуйте себя свободно, создавая свой собственный корневой редуктор! -
Хранилище Redux сохраняет полное дерево состояния, возвращенное корневым редуктором.
Это новое дерево теперь является следующим состоянием вашего приложения! Каждый обработчик, зарегистрированный в
store.subscribe(listener), будет теперь вызван; обработчики могут вызватьstore.getState(), чтобы получить текущее состояние.Теперь интерфейс пользователя может быть обновлен, чтобы отразить новое состояние. Если вы используете привязки, такие как React Redux, на этом этапе вызывается
component.setState(newState).
Дальнейшие шаги
Теперь, когда вы знаете, как работает Redux, давайте подключим его к приложению React.
Примечание для опытных пользователей
Если вы уже знакомы с основными понятиями и уже выполнили это руководство, не забудьте ознакомиться с асинхронным потоком в расширенном руководстве, чтобы узнать, как составные элементы преобразуют асинхронные действия перед тем, как они достигнут редуктора.
© 2015–2017 Dan Abramov
Licensed under the MIT License.
http://redux.js.org/docs/basics/DataFlow.html