簡體   English   中英

來自在React.js UseEffect掛鈎中創建的事件處理程序的訪問狀態

[英]Access state from Event Handler created within React.js UseEffect Hook

在我的組件中,我要在useEffect掛鈎中設置一個事件偵聽器:

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

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

..但是當我調用onSubtitleClick ,我的狀態是陳舊的-這是原始值。 示例代碼在這里 如何從使用useEffect設置的事件處理程序中訪問狀態?

您的事件偵聽器在定義的環境中注冊了一個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>

我認為基本的addEventListener創建了自己的版本的封閉count獨立於父組件的。 一個簡單的解決方法是允許useEffect函數在更改時重新運行(刪除[] arg):

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM