在特定条件下解锁反应历史推送

问题描述 投票:0回答:2

当升级到 React Router 6 时,由于一些围绕路由和 redux 的自定义架构以及 React router 删除了 Prompt 组件,我不得不使用基于历史记录包的自定义阻止模块(无论如何,它都在我的应用程序中)。我在 useEffect 调用中创建了它,如下所示:

useEffect(() => {
  if (shouldBlock) {
    const unblock = history.block(transition => {
      const url = transition.location.pathname;
      openPromptDialog(url, unblock);
    });
  }
}, [shouldBlock]);

一切看起来都正常,但我发现了一些小错误。当我们想要离开带有脏表单的页面时,

openPromptDialog
会打开一个自定义确认对话框(
shouldBlock
为true)。这部分有效,但当我们在页面上保存表单并且想要离开时,它就不起作用了。表格不再脏了,所以
shouldBlock
false
,但是因为它曾经是
true
,我们没有机会解锁它,我也找不到方法来做到这一点。

请注意,我不想依赖react-router阻塞,因为我不(目前也不能)使用数据API

createBrowserRouter
,这是使用
useBlocker
所必需的。

reactjs react-router browser-history
2个回答
0
投票

您可以尝试使用此方法来解锁在 if (shouldBlock) 块之外声明的变量,并且可以在清理函数中访问该变量。当组件被卸载或者shouldBlock发生变化时,cleanup函数会被执行,如果存在的话会调用unblock。这可以确保即使 shouldBlock 变为 false,也可以正确删除阻塞。

useEffect(() => {
  let unblock;

  if (shouldBlock) {
    unblock = history.block(transition => {
      const url = transition.location.pathname;
      openPromptDialog(url, () => {
        unblock();
      });
    });
  }

  return () => {
    if (unblock) {
      unblock(); 
    }
  };
}, [shouldBlock]);

0
投票

一旦

shouldBlock
设置为 true,您拥有的代码就不会解锁导航操作。

您可以在

shouldBlock
依赖项更新时返回清理函数来解锁导航操作。这将清除以前的所有阻止程序。

示例:

useEffect(() => {
  if (shouldBlock) {
    const unblock = history.block(transition => {
      const url = transition.location.pathname;
      openPromptDialog(url, unblock);
    });

    return unblock; // <-- unblock as cleanup function when set
  }
}, [shouldBlock]);

演示

Edit unblock-react-history-push-on-particular-condition

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.