簡體   English   中英

在 useState 掛鈎中設置 state 后反應 state 變量不准確

[英]React state variable not accurate after set state in useState hook

我有一個 React function 組件與舊版 JQuery 應用程序一起運行。 When calling an event handler on a JQuery element, passing in the current React state defaults to the initial state value and not the updated state value.

已驗證 x state 正在通過 useEffect 掛鈎進行更改,但在調用事件偵聽器時,x 設置為初始 state 值,而不是更新后的 state 值。

function MyComponent(props) {
   const [x, setX] = useState(false);

// On initial render
useEffect(() => {
   props.jQueryButton.addEventListener('click', onXSave)
}, [])

useEffect(() => {
    console.log("x changed " + x); // everytime onXChange is called, x 
    state is updated with the checked value, and this console.log shows 
    the correct state value
}, [x]);

onXChange = event => {
   setX(event.target.checked); // checked is true in this context
};

onXSave = event => {
  const obj = { x: x}; // x is false here, even though the state in this context shows it to be true.
  };
}

不顯示錯誤消息。 在上面的代碼中,我希望 x state 在 onXSave 方法調用中為真,但它一直顯示為假。

onXSave在初始渲染時添加為處理程序,因此x具有當時的值。 在每次渲染時重新創建onXSave並不重要,因為它從未使用過初始渲染。

要解決此問題,您可以將x放入ref

 unction MyComponent(props) { const [x, setX] = useState(false); const ref = useRef(); ref.current = x; // On initial render useEffect(() => { props.jQueryButton.addEventListener('click', onXSave) }, []) useEffect(() => { console.log("x changed " + x); // everytime onXChange is called, x state is updated with the checked value, and this console.log shows the correct state value }, [x]); onXChange = event => { setX(event.target.checked); // checked is true in this context }; onXSave = event => { const obj = { x: ref.current}; // by using ref, the value is always current }; }

您添加到eventListeneronXSave版本已過期 - 您僅在第一次渲染時添加一次,因此當x更新並導致重新渲染時,您的 useEffect 不會再次運行,您的jQueryButton仍將保留原來的 function,它已經關閉了一個過時的x版本。

你需要做兩件事:

  1. 在你的useEffect依賴數組中添加onXSave和你的jQueryButton作為依賴(所以當它重新渲染時,你的 function 的當前版本連接到你的 eventListener)
  2. 通過從useEffect返回清理 function 來刪除重新渲染時的舊事件偵聽器。

所以像:

function MyComponent(props) {
   const [x, setX] = useState(false);

// On initial render
useEffect(() => {
   props.jQueryButton.addEventListener('click', onXSave)
   return ()=> props.jQueryButton.removeEventListener('click', onXSave)
}, [onXSave, props.jQueryButton])

useEffect(() => {
    console.log("x changed " + x); // everytime onXChange is called, x 
    state is updated with the checked value, and this console.log shows 
    the correct state value
}, [x]);

onXChange = event => {
   setX(event.target.checked); // checked is true in this context
};

onXSave = event => {
  const obj = { x: x}; // x is false here, even though the state in this context shows it to be true.
  };


}

暫無
暫無

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

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