предисловие
Я считаю, что у многих друзей-новичков должно быть много путаницы и сомнений по поводу взаимосвязи и различий между React, Redux и React-Redux. Здесь мы подробно разберем их.
React
: отвечает за отрисовку пользовательского интерфейса компонента;
Redux
: центр обработки данных;
React-Redux
: Подключение компонентов и дата-центров, то есть подключение React и Redux.
React
React в основном используется для реализации интерфейса пользовательского интерфейса и представляет собой фреймворк, ориентированный на уровень представления. Для некоторых небольших проектов, если взаимодействия данных не много, его можно хорошо реализовать, используя только React.
В традиционном режиме разработки страницы необходимо несколько раз использовать DOM для обновления страницы.Все мы знаем, что работа с DOM вызовет большие проблемы с производительностью. Предложение React состоит в том, чтобы сократить работу DOM для повышения производительности, то есть Virtual DOM.
Virtual DOM
Виртуальный DOM эквивалентен виртуальному пространству, а React работает на основе Virtual DOM.
Его рабочий процесс таков: когда есть данные, которые необходимо обновить, он сначала рассчитает виртуальный DOM и сравнит его с последним виртуальным DOM, чтобы получить разницу в структуре DOM, а затем будут только те части, которые необходимо изменить. обновляться партиями до реального в DOM.
Когда дело доходит до расчета Virtual DOM, в React используется алгоритм react-diff. Все мы знаем, что традиционный алгоритм diff сравнивает каждый узел по очереди посредством рекурсии, что неэффективно, а сложность алгоритма достигает O(n^3), где n — общее количество узлов в дереве.
Согласно стратегии реагирования diff:
- Операций перемещения узлов DOM по уровням в веб-интерфейсе очень мало, и ими можно пренебречь;
- Два компонента с одним и тем же классом будут генерировать похожие древовидные структуры, а два компонента с разными классами будут генерировать разные древовидные структуры;
- Для группы дочерних узлов одного уровня их можно отличить по уникальному идентификатору.
React оптимизировал алгоритм для сравнения деревьев, компонентов и элементов соответственно:
-
tree diff
: сравнивать деревья иерархически, два дерева будут сравнивать только узлы на одном уровне -
component diff
:
- Если это компонент того же типа, продолжайте сравнивать виртуальное дерево DOM в соответствии с исходной стратегией.
- Если нет, компонент оценивается как грязный компонент, и все дочерние узлы во всем компоненте заменяются.
- Для одного и того же типа компонента возможно, что в его виртуальном DOM нет изменений.Если вы можете точно знать это, это может сэкономить много времени на вычисление различий, поэтому React позволяет пользователям использовать shouldComponentUpdate(), чтобы определить, является ли компонент должен быть diff.
-
element diff
: Когда узлы находятся на одном уровне, React diff предоставляет три операции с узлами: вставка, перемещение и удаление.
Вот сравнительная блок-схема всего алгоритма реакции diff:
Жизненный цикл реакции
React имеет в общей сложности 10 периодических функций (рендеринг повторяется один раз), эти 10 функций могут удовлетворить все наши потребности в операциях с компонентами, и их правильное использование может повысить эффективность разработки и производительность компонентов.
1. Компонент запускает 5 функций ловушек при инициализации:
getDefaultProps()
Установите реквизит по умолчанию, используемый в es6static dufaultProps={}
Установите свойства компонента по умолчанию. Выполняется только один раз за весь жизненный цикл.
getInitialState()
При использовании синтаксиса класса es6 такой функции-ловушки нет, вы можете определить this.state непосредственно в конструкторе. This.props доступен в этот момент.
-
componentWillMount()
Операция извлечения данных Ajax, запуск таймера.
Вызывается при инициализации компонента.Не вызывается при последующем обновлении компонента.Вызывается только один раз за весь жизненный цикл.В это время состояние может быть изменено.
render()
Здесь выполняются самые важные шаги React, создание виртуального дома, выполнение алгоритма сравнения и обновление дерева домов. В этот момент состояние не может быть изменено.
-
componentDidMount()
Начнется анимация, поле ввода автоматически сфокусируется
Вызывается после рендеринга компонента, вы можете получить и управлять узлом DOM через this.getDOMNode(), который вызывается только один раз.
2. При обновлении также запускаются пять функций ловушек:
componentWillReceivePorps(nextProps)
Не вызывается при инициализации компонента, вызывается, когда компонент принимает новые реквизиты. Запускается независимо от того, изменились ли реквизиты, переданные от родительского компонента к дочернему компоненту, или нет.
shouldComponentUpdate(nextProps, nextState)
Очень важная часть оптимизации производительности React. Вызывается, когда компонент принимает новое состояние или реквизиты, мы можем установить, одинаковы ли два реквизита и состояние до и после сравнения, если они одинаковы, вернуть false, чтобы предотвратить обновление, потому что одно и то же состояние свойства определенно сгенерирует то же самое дерево DOM, поэтому нет необходимости создавать новое дерево DOM и сравнивать старое дерево DOM для алгоритма сравнения, что значительно экономит производительность, особенно когда структура DOM сложна. Однако при вызове this.forceUpdate этот шаг пропускается.
componentWillUpdate(nextProps, nextState)
Он не вызывается, когда компонент инициализируется, он вызывается только тогда, когда компонент собирается обновиться, и в это время состояние может быть изменено.
render()
не так много, чтобы сказать
componentDidUpdate()
Он не вызывается при инициализации компонента, а вызывается после обновления компонента, и в это время можно получить узел dom.
3. Удалить функцию хука
-
componentWillUnmount()
Очистить таймер
Вызывается, когда компонент собирается выгрузиться, в это время необходимо очистить некоторые прослушиватели событий и таймеры.
Redux
Redux — это архитектурный шаблон, разработанный на основе Flux.
Три принципа Redux
- Уникальный источник данных
- Статус только для чтения
- Изменения данных могут быть сделаны только через чистые функции (редьюсеры).
Редукторное ядро API
Redux в основном состоит из трех частей: хранилища, редуктора и действия.
store
Ядром Redux является хранилище, которое генерируется методом createStore(reducer, defaultState), предоставляемым Redux, который генерирует три метода: getState(), dispatch() и subscribe().
- getState(): сохраненные данные, дерево состояний;
- dispatch(action): отправить действие и вернуть действие, что является единственным способом изменить данные в хранилище;
- подписка (прослушиватель): зарегистрируйте прослушиватель, который вызывается при изменении хранилища.
reducer
Редьюсер — это чистая функция, которая вычисляет новое состояние на основе предыдущего состояния и действия.
reducer(previousState,action)
action
Действие — это, по сути, объект JavaScript, который должен содержать поле типа для представления выполняемого действия, а другие поля можно настраивать в соответствии с требованиями.
const ADD_TODO = 'ADD_TODO'
{
type: ADD_TODO,
text: 'Build my first Redux app'
}
Интегрировать
Взаимодействие между этими тремя можно резюмировать на следующем рисунке:
React-Redux
Сам по себе Redux не имеет ничего общего с React, это просто центр обработки данных, а React-Redux связывает их между собой.
React-rRedux предоставляет два метода: connect и Provider.
connect
connect подключает компоненты React к хранилищу Redux. connect на самом деле является функцией более высокого порядка, которая возвращает новый класс компонента, который был подключен к хранилищу Redux.
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
TodoList — это компонент пользовательского интерфейса, а VisibleTodoList — это компонент-контейнер, автоматически сгенерированный react-redux через метод подключения.
-
mapStateToProps
: извлеките необходимые части из дерева состояний Redux в качестве реквизита для передачи текущему компоненту. -
mapDispatchToProps
: передать событие ответа (действие), которое необходимо привязать к компоненту, в качестве реквизита.
Provider
Провайдер реализует глобальный доступ к хранилищу, передавая хранилище каждому компоненту.
Принцип: используя контекст React, контекст можно передавать между компонентами.
Суммировать
Следующая диаграмма иллюстрирует рабочий процесс между тремя: