繁体   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