Я знаю, что это может быть странным случаем, но я пытаюсь понять внутренности реакционных хуков. У меня есть компонент, который отображает простую кнопку для увеличения счетчика, и компонент App
, который его использует:
function Comp(props) {
return <button onClick={props.onClick}>Increment</button>;
}
function App() {
const [count, setCount] = useState(5);
const cacheRef = useRef();
const onBtnClick = () => {
console.log(count);
setCount(count + 1);
};
const getIncrementBtn = () => {
if (!cacheRef.current) {
cacheRef.current = <Comp onClick={onBtnClick} />;
}
return cacheRef.current; //this doesn't work
// return <Comp onClick={onBtnClick} />; //this works
};
return (
<div className="App">
<h2>You clicked {count} times!</h2>
{getIncrementBtn()}
</div>
);
}
Если getIncrementBtn
всегда возвращает новый экземпляр Comp
, все работает. Однако, если я пытаюсь кэшировать Comp
с помощью useRef
, то count
всегда возвращает начальное значение (5
). Я могу заставить его работать с кешированием, если я заменю setCount(count + 1)
на setCount(c => c + 1)
, что, я думаю, решает проблему обновления состояния, но значение count
внутри onBtnClick
по-прежнему 5
, поэтому, если бы я хотел сделатьЯ не мог выполнить какие-либо вычисления, основанные на текущем состоянии.
Я уже нашел способ обойти это, полностью отбросив useState
и используя только useRef
, но мне больше интересно понять, почему это не так. не работает в первую очередь. Я предполагаю, что это как-то связано с замыканиями и передачей копии count
в какой-то момент, но после прочтения некоторых статей я не мог сказать, что точно понимаю, почему это не сработало, как ожидалось и в какой момент count
было скопировано.
Полный пример: CodeSandbox
Любая помощь будет приветствоваться - либо объяснение, либо ссылка на статью / блог, объясняющий такое поведение useState
.
Спасибо