React上下文在超时不在

发布于 2025-01-22 18:50:08 字数 690 浏览 0 评论 0原文

我正在使用React App上下文存储一系列“警报对象”,这基本上是可能发生的任何错误,我想在网站的右上角显示。我遇到的问题是,上下文在超时内部没有最新。我为测试所做的工作是获得一个按钮,在单击上下文时,将一个警报对象添加到上下文中,另一个组件在上下文中通过该数组映射并呈现它们。我希望它们在5秒后消失,因此我添加了一个超时,该超时会过滤刚刚添加并删除它的项目。问题在于,在超时范围内,Alerts数组似乎具有与5秒前相同的值,而不是使用最新值导致问题和元素未被过滤。我不确定我的逻辑是否有问题,还是我正在使用上下文错误的事情?

        onClick={() => {
          const errorPopup = getPopup(); // Get's the alert object I need
          context.setAlerts([errorPopup, ...context.alerts]);
          setTimeout(() => {
            context.setAlerts([
              ...context.alerts.filter(
                (element) => element.id !== errorPopup.id,
              ),
            ]);
          }, 5000);
        }}

I am using react app context to store an array of "alerts objects" which is basically any errors that might occur and I would want to show in the top right corner of the website. The issue I am having is that the context is not being up to date inside a timeout. What I have done for testing is gotten a button to add an alert object to the context when clicked and another component maps through that array in the context and renders them. I want them to disappear after 5 seconds so I have added a timeout which filters the item that got just added and removes it. The issue is that inside the timeout the context.alerts array seems to have the same value as 5 seconds ago instead of using the latest value leading to issues and elements not being filtered out. I am not sure if there's something wrong with my logic here or am I using the context for the wrong thing?

        onClick={() => {
          const errorPopup = getPopup(); // Get's the alert object I need
          context.setAlerts([errorPopup, ...context.alerts]);
          setTimeout(() => {
            context.setAlerts([
              ...context.alerts.filter(
                (element) => element.id !== errorPopup.id,
              ),
            ]);
          }, 5000);
        }}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦幻之岛 2025-01-29 18:50:08
onClick={() => {
          const errorPopup = getPopup(); // Get's the alert object I need
          context.setAlerts([errorPopup, ...context.alerts]);
          setTimeout(() => {
            context.setAlerts(alerts => [
              ...alerts.filter(
                (element) => element.id !== errorPopup.id,
              ),
            ]);
          }, 5000);
        }}

这应该解决。直到react@17 setStates在事件处理程序中进行批处理(在React@18 All SetStates甚至是异步的setstates ),因此您需要使用最新鲜的状态在第二setAlerts中进行更新。

为了安全起见,使用cb语法也是第一个setstate中的一个好练习。

onClick={() => {
          const errorPopup = getPopup(); // Get's the alert object I need
          context.setAlerts([errorPopup, ...context.alerts]);
          setTimeout(() => {
            context.setAlerts(alerts => [
              ...alerts.filter(
                (element) => element.id !== errorPopup.id,
              ),
            ]);
          }, 5000);
        }}

This should fix it. Until react@17 the setStates in an event handler are batched ( in react@18 all setStates are batched even the async ones ), hence you need to use the most fresh state to make the update in second setAlerts.

To be safe it's a good practice using the cb syntax in the first setState as well.

套路撩心 2025-01-29 18:50:08

我认为修复程序将是将Context.SetAlerts(...)移动到一个单独的函数(例如removePopupPromContext(ID:String)),然后通过将errorpopopup.id作为参数来调用SettiMeout中的此函数。

我不确定您的context.setAlerts的实现,但是如果它基于SetState函数,那么您也可以使用一个函数在setState中使用一个可以让您跳过创建的函数,也可以做一些类似的反应。可能会轻轻翻译成的额外功能:

setContext(prevContextState =>({
  ...prevContextState, 
  alerts: prevContextState.alerts.filter(your condition)
)})

I think the fix would be to move context.setAlerts(...) to a separate function (say removePopupFromContext(id:string)) and then call this function inside the setTimeout by passing the errorPopup.Id as parameter.

I'm not sure of your implementation of context.setAlerts, but if it's based on just setState function, then alternatively, you could do also something similar to how React let's you access prevState in setState using a function which will let you skip the creation of the extra function which may lightly translate to:

setContext(prevContextState =>({
  ...prevContextState, 
  alerts: prevContextState.alerts.filter(your condition)
)})
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文