Я использовал useState для управления состояниями в своем приложении react. Все было хорошо и прекрасно, пока мне не пришлось управлять более чем тремя состояниями в один клик. Иногда состояние требовало нескольких операций, что делало его еще более сложным.
Что именно представляет собой useReducer?
useReducer используется для управления состоянием, как альтернатива useState, когда состояние становится сложным и включает в себя несколько подзначений.
Я предпочитаю использовать useReducer, когда у меня есть три или более состояний, чтобы управлять всеми мутациями состояний в одном месте.
Необходимые условия:
Оператор Switch,
оператор Spread,
useState.
Как это работает?
Сначала давайте посмотрим, как работает reduce в JavaScript.
Функция reduce выполняет функцию reducer, которая принимает массив и возвращает одно значение. Здесь мы использовали функцию reduce + оператор spread для сложения четных и нечетных чисел массива.
const reducer = (accumulator, currentValue) =>
{
return currentValue%2===0?
{...accumulator,even:accumulator.even+currentValue}:
{...accumulator,odd:accumulator.odd+currentValue}
}
[3, 4, 7, 8].reduce(reducer,{odd:0,even:0})
Мы используем оператор spread для получения предыдущего значения
затем манипулируем объектом в зависимости от того, является ли текущее значение четным или нечетным.
{even:accumulator.even+currentValue}
. Здесь accumulator.even -> — это четное значение, которое ранее хранилось в объекте accumulator, а currentVaulue — это текущий элемент массива, который передается через функцию reduce.
Функция reducer вернет нам одно значение. {odd:10,even:20}
.
Включение функции useReducer
const [state,dispatch]=useReducer(reducerFunction,stateVariables)
В React функция useReducer, по сути, принимает функцию reducer
и возвращает объект state, к которому мы можем привязать компоненты, и функцию диспетчеризации, которой мы отправляем действия.
переменные состояния:
Переменные состояния — это данные, которые мы создаем для того, чтобы манипулировать ими.
Например, в useState мы передаем значение напрямую
value=0
const [oddSum,setOddSum]=useState(value)
const [evenSum,setEvenSum]=useState(value)
В reducer мы сначала создаем объект
const stateVariables={
value:0
}
Значения в переменных состояния манипулируются с помощью функции reducer.
Функция редуктора:
Функция reducerFunction принимает два параметра state и action.
Состояние — это данные {переменная состояния, которую мы создали при создании useReducer}, которыми мы будем манипулировать.
Функция получает действие от компонента, которому передается диспетчерская функция.
function reducerFunction(state,action){
////
}
Передача функции в компонент.
В функции диспетчеризации, в нашем компоненте, мы передаем значения «type» и «payload».
Возможное действие определяется «типом», который передается в функции диспетчеризации.
А любые конкретные значения/информация/данные/объект передаются через полезную нагрузку и используются для манипулирования переменными состояния.
Например
<button onClick=()=>dispatch({type:"incrementHandler",payload:10})>
Increment by 10
</button>
<button onClick=()=>dispatch({type:"decrementHandler",payload:10})>
Decrement by 10
</button>
<button onClick=()=>dispatch({type:"reset"})>
Reset</button>
В конце концов, функция reducer — это, по сути, оператор switch, определяющий все возможные действия, которые может выполнить контекст, и обновляющий только ту часть глобального состояния, которая связана с этим действием.
например
function reducerFunction(state,action){
switch(action.type){
case "incrementHandler" :
return {...state,value:state.value+action.payload}
case "decrementHandler" :
return {...state,value:state.value-action.payload}
case "reset":
return {...state,value:0}
default:
return {...state}
}
}
Здесь:
мы используем оператор spread для получения предыдущих
значения в объекте state и присваиваем новое значение «value».
state.value получит значение в предыдущем состоянии и добавит его к action.payload
т.е. action.payload для типов: «инкремент» и «декремент» равна 10, поэтому когда я
нажимаю на Increment : значение =0+10=10
нажимаю на Increment : значение = 10+10=20
нажать на Уменьшение: значение= 20-10=10
нажать на сброс: значение=0
и т.д.
Фрагмент кода .
import { useReducer } from "react";
export default function App() {
function reducerFunction(state, action) {
switch (action.type) {
case "incrementHandler":
return { ...state, value: state.value + action.payload };
case "decrementHandler":
return { ...state, value: state.value - action.payload };
case "reset":
return { ...state, value: 0 };
default:
return { ...state };
}
}
const stateVariables = {
value: 0
};
const [state, dispatch] = useReducer(reducerFunction, stateVariables);
return (
<div className="App">
<button
onClick={() => dispatch({ type: "incrementHandler", payload: 10 })}
>
Increment by 10
</button>
<button
onClick={() => dispatch({ type: "decrementHandler", payload: 10 })}
>
Decrement by 10
</button>
<button onClick={() => dispatch({ type: "reset" })}>Reset</button>
<div>{state.value}</div>
</div>
);
}