предисловие
Эта статья не говорит о конкретных приложениях реагирования, Redux, Action, редуктора, просто простое объяснениеПочему редюсеры должны быть чистыми функциями, Эта статья подходит для студентов, которые имеют некоторый опыт разработки редуксов.
Учащиеся, использовавшие React, должны быть знакомы с Redux, поскольку Redux может обеспечить предсказуемое управление состоянием. В приложении все состояние хранится в одном хранилище в виде дерева объектов, и единственный способ изменить состояние — запустить действия, иreducerОн используется для написания специализированных функций, определяющих, как каждое действие изменяет состояние приложения.
Как сказано на официальном сайте, редьюсер — это чистая функция, которая принимает старое состояние и действие и возвращает новое состояние.(previousState, action) => newState
Вот наш вопрос:
Почему редюсер должен быть чистой функцией?
Почему он должен возвращать новое состояние?
Почему бы не вернуть прежнее состояние?
Как пишется исходный код редукса?
написание чистой функции
Давайте сначала посмотрим на обычный случай, обычно у нас есть следующие способы вернуть новое состояние:
- вернуть новый объект напрямую
- Используйте Object.assign() для возврата нового объекта
- Вернуть новый объект с помощью Immutable.js
Состояние, возвращаемое редюсером, сохраняется в хранилище Redux, это новое дерево хранилища — следующее состояние приложения, все подпискиstore.subscribe(listener)
Слушатели будут вызваны, и слушатель может быть вызванstore.getState()
Получить текущее состояние На этом этапе мы можем использовать новое состояние для обновления пользовательского интерфейса.setState(newState)
Что такое чистая функция?
Вот краткое объяснение того, что такое чистая функция?
- Один и тот же ввод всегда возвращает один и тот же вывод
- Не изменять входное значение функции
- Независимость от состояния внешней среды
- Нет побочных эффектов
Почему редюсер должен быть чистой функцией?
Давайте сначала поэкспериментируем, что произойдет, если редьюсер не будет чистой функцией? Давайте преобразуем редюсер приведенного выше кода и изменим состояние напрямую, вместо того, чтобы возвращать новое состояние.
После изменения кода мы обнаружили, что при срабатывании Action страница не менялась, почему так?
Давайте посмотрим на исходный код Redux:
Через исходный код мы обнаружили, чтоvar nextStateForKey = reducer(previousStateForKey, action)
, nextStateForKeyhasChanged = hasChanged || nextStateForKey !== previousStateForKey
сравнить, соответствуют ли старые и новые объекты,Этот метод сравнения сравнивает место хранения двух объектов., то есть метод поверхностного сравнения, поэтому, когда наш редьюсер напрямую возвращает старый объект состояния, Redux думает, что ничего не изменилось, в результате чего страница не обновляется.
Почему Redux разработан таким образом?
Потому что единственный способ сравнить, являются ли все свойства в двух объектах javascript одинаковыми, — это провести глубокое сравнение.Однако в реальных приложениях код для глубокого сравнения очень большой, что очень требовательно к производительности и требует большого количества сравнений, поэтому Эффективное решение состоит в том, чтобы оговорить, что при любом изменении разработчик должен возвращать новый объект, а при отсутствии изменений разработчик возвращает исходный объект, поэтому redux проектирует редюсер как чистую функцию. .