Хук useReducer похож на хук useState, но там, где useState лучше всего подходит для управления примитивными значениями (например, строками, числами и логическими значениями), useReducer лучше всего подходит для манипулирования объектами с несколькими свойствами.

// useState (from react docs):
const [name, setName] = useState('Taylor');

// useReducer (from react docs):
function reducer(state, action) {
  // ...
}

function MyComponent() {
  const [state, dispatch] = useReducer(reducer, { age: 42 });
  // ...
}

В то время как useState напрямую устанавливает значение, которым он управляет, с помощью второго элемента, возвращаемого хуком, useReducer предоставляет функцию dispatch, которую затем можно вызвать с объектом действия. Когда dispatch вызывается с действием, функция, определенная вне компонента, будет вызываться со старым состоянием и действием. Как правило, эта функция будет содержать оператор switch, который будет использоваться, чтобы решить, как создать новое состояние.

Наш пример

Распространенным вариантом использования является форма, в которой мы обновляем существующие данные. Форма может извлекать эти существующие данные на основе ключа (ов) в базе данных (идентификаторы) и отображать эти данные. Затем пользователь будет использовать поля формы для редактирования каждого свойства объекта, кроме идентификаторов, прежде чем отправить результат обратно в серверную часть для хранения в базе данных.

Например, предположим, что у нас есть форма для обновления адреса, которая имеет этот тип:

interface Address {
  id: number | string;
  line_1: string;
  line_2: string;
  city: string;
  state: string;
  zip: string;
  user_id: number | string;
}

Первое свойство, id, идентифицирует адрес в своей таблице, а последнее свойство, user_id, идентифицирует пользователя, у которого есть этот адрес в таблице пользователей. Поскольку это свойства, которые идентифицируют объекты в базе данных, мы не будем их обновлять (предположим, что наши пользователи не переезжают друг к другу в дома).

Изменения состояния

Прежде чем мы начнем программировать, давайте подумаем, как будет работать наше состояние. Наш компонент получит идентификатор адреса в свойствах, например:

function UpdateAddressForm({address_id}: {address_id: number | string}) {
    //TBD
}