React 上下文不随状态更新

React Context does not update with state

我有这样的代码;

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() 结果始终检查 returns undefined,允许添加重复的 toasts。

然而,ToastPortal 确实收到了更新后的状态值。

Sandbox

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

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

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