微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

React Context 不随状态更新

如何解决React Context 不随状态更新

我有这样的代码

const ToastContextProvider: React.FC = ({ children }) => {
  const [toasts,setToasts] = useState<ToastDeFinition[]>([]);

  const addToast = useCallback(
    (toast: ToastDeFinition) => {
      if (toasts.find(({ id }) => id === toast.id)) {
        return logger.warn('Attempted to add a new toast with a duplicate ID!',{
          toast,});
      }

      setToasts((toasts) => [...toasts,{ ...toast }]);
    },[toasts]
  );

  const removetoast = (id: string) => {
    setToasts((toasts) => toasts.filter((toast) => toast.id !== id));
  };

  const value = {
    addToast,removetoast,};

  return (
    <ToastContext.Provider value={value}>
      <ToastPortal toasts={toasts} />
      {children}
    </ToastContext.Provider>
  );
};

这个想法是我会在一个组件中调用 addToast,其中 toast 是一个像这样的对象;

{
    id: 'test',message: 'Hello world',}

如果 ID 存在于 toasts 状态中,则不允许使用。但是,在 addToast调用 console.log(toasts) 总是记录一个空数组,并且 arr.find() 检查总是返回 undefined as结果,允许添加重复的 toast。

ToastPortal 会收到更新后的状态值。

Sandbox

解决方法

addToast 添加到您的 useEffect 的依赖项数组,以便关闭当前 addToast 值的最新 toasts 函数参与您的间隔逻辑。一个空的依赖数组意味着在开始时创建的 addToast 被重复调用,并且该方法关闭了 toasts 的初始值 []

  useEffect(() => {
    const interval = setInterval(() => {
      addToast({
        id: "test",msg: "testmsg"
      });
    },5000);

    return () => clearInterval(interval);
  },[addToast]);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。