useLocation 挂钩即使在硬刷新时也能保持状态

useLocation hook keeps states even on hard refresh

在处理一个项目时,我注意到 useLocation 钩子有一个奇怪的行为,我找不到解释。

我有一个按钮,单击该按钮会将您重定向到 EditOrder 页面并传递一个状态:

const navigate = useNavigate();

const handleClick = (data) => {
    navigate("edit-order", {state: {order: data}})
};

EditOrder 页面中,我使用 UseEffect 钩子检查是否提供了 state,如果没有,用户将被重定向到另一个页面:

const { state } = useLocation();

const navigate = useNavigate();

useEffect(() => {
    if (!state) {
        navigate("some-page");
    }
}, []);

奇怪的是,当我刷新页面时,我仍然可以访问它,如果我 console.log(state.order) 数据仍然存在,即使我使用 ctrl + shift + r 重新加载,状态也保持不变,这也发生在 empty cache and hard reload option 中(在 chrome 和 edge 中都尝试过)。

但是,当我复制 URL 并将其粘贴到新选项卡中时,我立即被重定向到“某些页面” console.log(state) 将显示 null.

我检查了 cookie 和本地存储,但在那里找不到状态数据。

有人可以解释为什么会发生这种情况以及如何保存状态数据吗?

编辑:

这是一个显示此行为的 youtube video

视频中的代码可以在 this sandbox 中找到,当您 运行 沙盒中的代码时,它 运行 应该会在刷新时重置所有状态,但是运行在本地(在 2 台不同的计算机上)会出现此问题。

A git repo about location.state

React 的 useLocation is based on the history library,它在网络应用程序中使用 BrowserHistory

Some browsers,如 Chrome,在会话之间保持 BrowserHistory 状态,而其他(如 Firefox)则不会。

这可能就是您在本地看到此行为但在沙盒中看不到的原因。 CodeSandbox 的浏览器似乎在刷新时清除了历史状态。这也是为什么,如果您将 URL 复制到另一个选项卡,则重定向有效。 BrowserHistory 对于单个选项卡是本地的。

简而言之,这是有意为之的行为。您需要手动清除历史状态或将您的应用程序状态存储在其他地方(如果您想跨页面保持 useContext 可能是一个不错的选择,但 而不是 跨刷新)。