React 可堆叠 snackbars/toasts

React stackable snackbars/toasts

我正在创建自己的简单 snackbar/toast 堆垛机。但是,我在有序地排队时遇到了问题。从 snackbar 队列中删除 snackbar 会导致重新呈现和奇怪的行为。

基本流程: 单击一个按钮会触发 addSnack 函数,该函数由 withSnackbar HOC 提供。

从触发的函数中获取参数,并相应地创建一个小吃并将其添加到小吃店列表中。

最后,我们渲染小吃店列表。

每个小吃店控制自己的出现和消失,并由超时控制。超时后,它调用 removeSnack 函数,该函数假设从列表中删除第一个零食。

codesandbox

例如,如果您在短时间内单击按钮四次。渲染的很好,但是删除第一个的时候,全部消失又异常出现。

我知道部分原因是状态重新渲染错误,但是,我不确定如何以优雅地处理删除而不影响其他零食的渲染的方式来处理它。

如果您查看 splice 文档,您会注意到它返回的是已删除元素的数组,而不是初始数组。

可以通过拼接更正然后更新:

snacks.splice(-1, 1);
addSnacks(snacks);

但是您仍然会有一些奇怪的行为,您可能需要使用 keyed list 来解决这个问题。

因此,经过数小时的反复试验,我找到了目前有效的解决方案。在州外移动和阅读零食有助于解决奇怪的渲染问题,并且我能够创建一个运行良好的消息队列。

工作示例 Codesandbox

我有同样的问题,我看到了你的解决方案,但我真的想找出它发生的原因 - 这就是原因:

当您从异步函数的回调调用 useState 挂钩时,您应该使用挂钩的回调格式以确保您使用的是最新值。示例:

const [messages, setMessages] = useState([]);

const addMessage = ( message ) => {
  setMessages( prevMessages => {//prevMessages will be the latest value of messages
    return [ ...prevMessages, message ];
  });
};

const removeMessage = ( index ) => {
  setMessages( prevMessages => {//prevMessages will be the latest value of messages
    let newMessages = [...prevMessages];
    newMessages.splice( index, 1 );
    return newMessages;
  });
};