簡體   English   中英

在自定義反應掛鈎中創建的回調 function 未提供最新值

[英]Callback function created in custom react hook isn't being provided with an up to date value

在我在 react 中創建的自定義警報系統中,我有 2 個主要功能,一個自定義掛鈎:

function useAlerts(){
  const [alerts, setAlerts] = useState([]);
  const [count, setCount] = useState(0);

  let add = function(content){
    let remove = function(){
      console.log(`alerts was set to ${alerts} before remove`);
      setAlerts(alerts.slice(1));
    };

    let newAlert = 
    <div className = 'alert' onAnimationEnd = {remove} key = {count}>
      <Warning/>
      <span>
        {content}
      </span>
    </div>


    setAlerts([...alerts, newAlert]);
    setCount(count + 1);
  }

  return [alerts,add];
}

和另一個元素來顯示自定義掛鈎中的數據。

function Alerts(){
  let [alerts,add] = useAlerts();

  useEffect(() => {
    let handler = function(){
      add('test');
    };
    window.addEventListener('keyup',handler);
    return function(){
      window.removeEventListener('keyup',handler);
    }
  });

  return (
    <div className = 'alerts'>
      {alerts}
    </div>
  )
}

我當前遇到的問題是刪除回調 function,控制台看起來像這樣。

let remove = function(){
      console.log(`alerts was set to ${alerts} before remove`);
      /// expected output: alerts was set to [<div>,<div>,<div>,<div>] before remove
      /// given output: alerts was set to [] before remove
      setAlerts(alerts.slice(1));
};

我知道這是因為刪除 function 正在采用警報 state 的初始值,但我如何確保它保持最新值? React 似乎不允許在回調中使用 useEffect,所以我似乎有點卡住了。 是否將 object 中的值傳遞給 go 之類的?

我相信我在這里看到的問題是本地 React state 上的陳舊外殼。 使用功能 state 更新以正確地從以前的 state 更新,而不是在回調 scope 中關閉的任何內容。 事實上,使用功能 state隨時更新下一個 state取決於前一個狀態的值。 增加計數和突變 arrays 是需要功能性 state 更新的兩個主要示例。

function useAlerts() {
  const [alerts, setAlerts] = useState([]);
  const [count, setCount] = useState(0);

  const add = (content) => {
    const remove = () => {
      console.log(`alerts was set to ${alerts} before remove`);
      setAlerts(alerts => alerts.slice(1));
    };

    const newAlert = (
      <div className='alert' onAnimationEnd={remove} key={count}>
        <Warning/>
        <span>
          {content}
        </span>
      </div>
    );

    setAlerts(alerts => [...alerts, newAlert]);
    setCount(count => count + 1);
  }

  return [alerts, add];
}

暫無
暫無

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

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