Поскольку состояние не тесно связано с экземпляром компонента в функциональных компонентах, предыдущее состояние не может быть достигнуто в useEffect
без его предварительного сохранения, например, с помощью useRef
.Это также означает, что обновление состояния, возможно, было неправильно реализовано в неправильном месте, потому что предыдущее состояние доступно внутри setState
функции обновления.
Это хороший вариант использования для useReducer
, который предоставляет Redux-подобное хранилище и позволяетреализовать соответствующий шаблон.Обновления состояний выполняются явно, поэтому нет необходимости выяснять, какое свойство состояния обновляется;это уже ясно из отправленного действия.
Вот пример как это может выглядеть:
function reducer({ sendAmount, receiveAmount, rate }, action) {
switch (action.type) {
case "sendAmount":
sendAmount = action.payload;
return {
sendAmount,
receiveAmount: sendAmount * rate,
rate
};
case "receiveAmount":
receiveAmount = action.payload;
return {
sendAmount: receiveAmount / rate,
receiveAmount,
rate
};
case "rate":
rate = action.payload;
return {
sendAmount: receiveAmount ? receiveAmount / rate : sendAmount,
receiveAmount: sendAmount ? sendAmount * rate : receiveAmount,
rate
};
default:
throw new Error();
}
}
function handleChange(e) {
const { name, value } = e.target;
dispatch({
type: name,
payload: value
});
}
...
const [state, dispatch] = useReducer(reducer, {
rate: 2,
sendAmount: 0,
receiveAmount: 0
});
...