React Hooks - useState всегда возвращает начальное значение при использовании useRef в качестве кеша - PullRequest
0 голосов
/ 05 ноября 2019

Я знаю, что это может быть странным случаем, но я пытаюсь понять внутренности реакционных хуков. У меня есть компонент, который отображает простую кнопку для увеличения счетчика, и компонент 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.

Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...