简体   繁体   English

在自定义反应挂钩中创建的回调 function 未提供最新值

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

In a custom alert system I have created in react I have 2 main functions, a custom hook:在我在 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];
}

and another element to display the data within the custom hook.和另一个元素来显示自定义挂钩中的数据。

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>
  )
}

the current issue I have is with the remove callback function, the console will look something like this.我当前遇到的问题是删除回调 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));
};

I understand this is because the remove function is taking the initial value of the alert state, but how do I make sure it keeps an up to date value?我知道这是因为删除 function 正在采用警报 state 的初始值,但我如何确保它保持最新值? React doesn't seem to allow useEffect in a callback so I seem to be a bit stuck. React 似乎不允许在回调中使用 useEffect,所以我似乎有点卡住了。 Is passing the value in an object the way to go or something?是否将 object 中的值传递给 go 之类的?

The issue I believe I see here is that of stale enclosures over the local React state.我相信我在这里看到的问题是本地 React state 上的陈旧外壳。 Use functional state updates to correctly update from the previous state instead of whatever if closed over in callback scope.使用功能 state 更新以正确地从以前的 state 更新,而不是在回调 scope 中关闭的任何内容。 In fact, use functional state updates any time the next state depends on the previous state's value.事实上,使用功能 state随时更新下一个 state取决于前一个状态的值。 Incrementing counts and mutating arrays are two prime examples for needing functional state updates.增加计数和突变 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