Состояние доступа из обработчика событий, созданного в React.js. UseEffect Hook - PullRequest
0 голосов
/ 23 апреля 2019

В моем компоненте я настраиваю прослушиватель событий в хуке useEffect:

useEffect(() => {
  const target = subtitleEl.current;
  target.addEventListener("click", () => {
    console.log("click");
    onSubtitleClick();
  });

  return () => {
    target.removeEventListener("click", null);
  };
}, []);

.. но когда я звоню onSubtitleClick, мое состояние устарело - это исходное значение. Пример кода здесь . Как я могу получить доступ к состоянию из обработчика событий, который был настроен с помощью useEffect? ​​

Ответы [ 2 ]

1 голос
/ 23 апреля 2019

Ваш прослушиватель событий регистрирует функцию (ссылку), которая имеет count в качестве 0 в среде, в которой он определен, и когда происходит новый рендеринг, ваша ссылка не обновляется, которая зарегистрирована с этим элементом, и эта зарегистрированная ссылка на функцию по-прежнемузнает, что счетчик равен 0, хотя счетчик был изменен, но обновленная функция не была зарегистрирована, которая знает обновленное значение в своем контексте.Поэтому вам необходимо обновить прослушиватель событий новой ссылкой на функцию.

useEffect(() => {
    const target = subtitleEl.current;
    target.addEventListener("click", onSubtitleClick);

    return () => {
      console.log("removeEventListener");
      target.removeEventListener("click", onSubtitleClick);
    };
}, [onSubtitleClick]);

Однако вам не нужен этот грязный код для достижения того, что вы делаете сейчас, или тому подобное.Вы можете просто вызвать эту переданную функцию по клику и не присоединяться к элементу через ref, а напрямую в jsx.

<div
    className="panelText"
    style={{ fontSize: "13px" }}
    onClick={onSubtitleClick}
    ref={subtitleEl}
  >
    Button2
</div>
0 голосов
/ 23 апреля 2019

Я думаю, что в основном addeventlistener создает закрытие со своей собственной версией count, отдельной от родительского компонента.Простое исправление состоит в том, чтобы позволить функции useEffect повторно запускать изменения (удалите аргумент []):

useEffect(() => {
  const target = subtitleEl.current;
  target.addEventListener("click", () => {
    console.log("click");
    onSubtitleClick();
  });

  return () => {
    target.removeEventListener("click", null);
  };
}); // removed [] arg which prevents useeffect being run twice
...