function Counter() {
const [count, setCount] = useState(0);
const increment = () => {
setCount(prevCount => prevCount + 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
);
}
const increment = () => {
setCount(prevCount => prevCount + 1);
};
В этом случае setCount принимает функцию обратного вызова, которая получает предыдущее значение состояния (prevCount) и возвращает новое значение, основанное на предыдущем. Этот подход полезен, когда новое состояние зависит от предыдущего состояния. Это также гарантирует корректность обновления состояния, даже если функция increment вызывается многократно в быстром темпе.
const increment = () => {
setCount(count + 1);
};
В этом случае setCount обновляет состояние, используя текущее значение count. Этот подход прост и будет работать в большинстве случаев. Однако он может быть проблематичным, если increment вызывается многократно в быстром темпе, так как он не гарантирует корректность обновления состояния, особенно если обновление состояния асинхронно.
Использование функции обратного вызова (первый вариант) обычно рекомендуется, если новое состояние зависит от предыдущего, и если есть потенциально множественные обновления состояния. Это помогает избежать потери обновлений состояния и гарантировать корректность данных.
function useState(initialValue) {
// подсчитываем вызовы useState в компоненте
component.useStateCount++;
// если уже был вызов этого useState(т.е. это не первая отрисовка)
if (component.useStateCount in component.useStateCache)
// возвращаем результат из кэша
return component.useStateCache[component.useStateCount];
// если первый вызов - подготавливаем ответ вида [state, setState]
const useStateResult = [
initialValue,
function setState(callbackOrValue) {
// если аргумент setState - функция
if (typeof callbackOrValue === 'function') {
// вызываем её с предыдущем значением в качестве аргумента и присваиваем результат вызова в state
useStateResult[0] = callbackOrValue(useStateResult[0]);
} else {
// иначе просто присваиваем аргумент в state
useStateResult[0] = callbackOrValue;
}
// вызов обновления компонента
component.updateComounent();
}
];
// добавляем в кэш
component.useStateCache[component.useStateCount] = useStateResult;
// возвращаем
return useStateResult;
}