useReducer-использовать статьи
useReducer — используется с useContext
useReducer
Это продвинутый хук, предоставляемый React. Это не то же самое, что useEffect, useState, useRef и другие необходимые хуки. Без него мы можем нормально завершить разработку требований, но useReducer может сделать наш код более читабельным и ремонтопригодным. , предсказуемость .
Ниже мы будем разделены на три статьи с подробным описанием того, как использовать его в проекте.useReducer
:
- Часть 1. Основное введение в JavaScript
reducer
Понятие и его характеристики, друзья, знакомые с редюсером, редуксом и т.п., могут пропустить эту статью - Часть 2: Основное введение
useReducer
Как его использовать и его сценарии, а также преимущества useReducer - Третья часть: дальнейшее введение в использование useReducer в сложных проектах и сложных страницах.
что такое редуктор
reducer
Эта концепция постепенно становится популярной в JavaScript с появлением Redux. Но нам не нужно изучать Redux, чтобы понять Reducer. Проще говоря, редуктор — это функция(state, action) => newState
: получение состояния текущего приложения и инициированного действия, вычисление и возврат последнего состояния. Вот кусок псевдокода:
// 举个栗子 计算器reducer,根据state(当前状态)和action(触发的动作加、减)参数,计算返回newState
function countReducer(state, action) {
switch(action.type) {
case 'add':
return state + 1;
case 'sub':
return state - 1;
default:
return state;
}
}
Приведенный выше пример: состояние является значением типа number, редюсер изменяет состояние в соответствии с типом действия (сложение, вычитание) и возвращает конечное состояние. просто для связиreducer
Концепцию легче понять, вы можете изменить состояние для подсчета, но всегда помните, что подсчет по-прежнемуstate.
function countReducer(count, action) {
switch(action.type) {
case 'add':
return count + 1;
case 'sub':
return count - 1;
default:
return count;
}
}
Идемпотентность редукторов
Как видно из примера вышеreducer
По сути, чистая функция без какого-либо пользовательского интерфейса и побочных эффектов. Это означает, что при одних и тех же входных данных (состоянии, действии) функция-редуктор всегда будет возвращать один и тот же результат (newState), независимо от того, сколько раз она выполняется. Следовательно, с помощью функции редуктора легко вывести изменения состояния, а также проще выполнить модульное тестирование.
expect(countReducer(1, { type: 'add' })).equal(2); // 成功
expect(countReducer(1, { type: 'add' })).equal(2); // 成功
expect(countReducer(1, { type: 'sub' })).equal(0); // 成功
Понимание состояния и нового состояния
state
Это текущий объект состояния приложения, который можно понимать как состояние в React, с которым мы знакомы.
В приведенном выше примере состояние является базовым типом данных, но во многих случаях состояние может быть сложным объектом JavaScript, например, количество в приведенном выше примере может быть просто свойством в состоянии. Для этого сценария мы можем использовать назначение структуры ES6:
// 返回一个 newState (newObject)
function countReducer(state, action) {
switch(action.type) {
case 'add':
return { ...state, count: state.count + 1; }
case 'sub':
return { ...state, count: state.count - 1; }
default:
return count;
}
}
Есть два важных момента, которые следует помнить о приведенном выше коде:
-
Объект состояния, обрабатываемый редуктором, должен быть
immutable
, что означает, что никогда не изменяйте напрямую объект состояния в параметре, функция редуктора должна каждый раз возвращать новый объект состояния. -
Поскольку редюсер должен каждый раз возвращать новый объект, мы можем использовать ES6.присваивание деструктуризацииЧтобы создать новый объект и переопределить свойство состояния, нам нужно изменить его, как в примере выше.
Это выглядит идеально, но если наше состояние вложено в несколько слоев, реализация присваивания деструктуризации будет очень сложной:
function bookReducer(state, action) {
switch(action.type) {
// 添加一本书
case 'addBook':
return {
...state,
books: {
...state.books,
[bookId]: book,
}
};
case 'sub':
// ....
default:
return state;
}
}
Рекомендуется для таких сложных сценариев состоянияimmerВ ожидании решить неизменной библиотеку.
Почему состояние должно быть неизменяемым?
- Идемпотентность редукторов
Выше мы упоминали, что редукторы должны оставаться идемпотентными, более предсказуемыми и проверяемыми. Если каждый раз возвращается одно и то же состояние, нет гарантии, что результат будет одинаковым независимо от того, сколько раз оно выполняется.
- Схема сравнения состояний в React
React сравниваетoldState
а такжеnewState
Именно при использовании функции Object.is, если это один и тот же объект, ретрендер компонента не улетит.
Можно сослаться на официальный документbailing-out-of-a-dispatch.
понимание действия
действие: используется для представления инициированного поведения.
- Используйте тип для представления определенного типа поведения (вход в систему, выход из системы, добавление пользователя, удаление пользователя и т. д.).
- Используя данные, переносимые полезной нагрузкой (например, добавление книг, вы можете передавать определенную информацию о книгах), давайте в качестве примера возьмем действие addBook выше:
const action = {
type: 'addBook',
payload: {
book: {
bookId,
bookName,
author,
}
}
}
function bookReducer(state, action) {
switch(action.type) {
// 添加一本书
case 'addBook':
const { book } = action.payload;
return {
...state,
books: {
...state.books,
[book.bookId]: book,
}
};
case 'sub':
// ....
default:
return state;
}
}
Суммировать
На данный момент основное введение в контент, связанный с редуктором, завершено, и краткое резюме:reducer
это использованиеaction
Предоставленная информация будетstate
Чистая функция, которая преобразует из A в B, имеет следующие характеристики:
- Синтаксис: (состояние, действие) => новое состояние
- Неизменяемый: возвращайте newState каждый раз, никогда не изменяйте объект состояния напрямую
- Действие: обычный объект Action обычно состоит из типа и полезной нагрузки (необязательно).
- тип: Тип этой операции, который также является основой для условного суждения редуктора.
- Полезная нагрузка: Предоставляет данные, прикрепленные к операции.
В следующей статье мы перейдем к сути: как использовать useReducer для упрощения управления нашим состоянием.
Последняя практика, приветствуем всех, чтобы отметить нашуБлог фронтенд-команды Renrendai, все статьи также будут обновляться синхронно сЗнай колонкуа такжеСчет наггетс, мы еженедельно делимся несколькими высококачественными техническими статьями о внешнем интерфейсе. Если вам понравилась эта статья, я надеюсь, что вы можете поставить палец вверх.