You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击浏览器后退按钮时如何强制React组件恢复初始状态?

如何在通过浏览器「后退」按钮进入页面/组件时强制恢复初始状态?

最简示例

  • 加载下方的HTML文件
  • 修改状态
  • 加载其他网站
  • 点击浏览器「后退」按钮

此时希望页面恢复初始状态,而非修改后的状态。

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Try state</title></head>
<body>
    <script>
        // (You can check window.state in the DEV console)
        window.state = 'initial state';
    </script>
    <p id="state-display">static content</p>
    <button onclick="state = 'changed state'; document.getElementById('state-display').innerHTML = state;">change state</button>
</body>
</html>

具体场景

我通过调用window.location.href = url切换页面,同时设置React状态以显示loading ...提示,直到新页面加载完成。

期望点击「后退」按钮时,前一页能重新加载初始状态,但浏览器似乎加载的是页面离开时的最后状态:

  • 显示页面A
  • 用户点击前往页面B的按钮
  • 设置状态为isLoading并调用window.location.href = pageB
  • 用户在页面B点击浏览器「后退」按钮回到页面A时,状态仍为isLoading,而非通过链接或地址栏访问时的初始状态

示例代码:

import React from 'react';
import { createRoot } from 'react-dom/client';

// -- just some test state
const getNextState = (function(){
    const values = [ 'cat', 'dog', 'fish', 'bird', 'kangaroo' ];
    let index = 0;
    return function(){
        const current = index;
        index = index < values.length - 1 ? index + 1 : 0;
        return values[ current ];
    };
})();

// --
function App() {
    const [ state, setState ] = React.useState(() => getNextState() );

    // --
    // can't set state here, because `useEffect` hook is
    // not (always) called when clicking on "back" button
    // --
    React.useEffect(() => {
        console.log('mounted');
    }, []);

    // -- set state and change url
    const goToPage = function( page ){
        setState( '...loading' );
        window.location.href = page;
    };

    return <div>
        <h1>{ window.location.search === '?page2' ? 'Page 2' : 'Page 1' }</h1>
        <p>{ state }</p>
        <button onClick={ () => { goToPage('/?page1'); } }>go to page 1</button>
        <button onClick={ () => { goToPage('/?page2'); } }>go to page 2</button>
        <button onClick={ () => { setState( getNextState() ); } }>change state</button>
    </div>;
}

// --
const root = createRoot(
    document.getElementById('root')!
);

root.render(
  <React.StrictMode>
      <App />
  </React.StrictMode>
);

注意1: 该问题仅在生产构建(如yarn build、yarn start)中出现。
注意2: 此简化示例中Chrome和Firefox表现一致,但在使用Redux和NextJs的实际项目中,仅在Chrome中能稳定复现该问题。
注意3: 我接受路由修改建议,但部分页面为静态预渲染,需在middleware.ts中做重定向,无法仅使用客户端路由。

无效方案

点击「后退」按钮时,似乎不会执行任何hooks(如useEffect),甚至不会触发DOMContentLoaded事件。

更新

该行为并不一致,目前我的Chrome已不再出现此问题,但Firefox仍存在。


内容的提问来源于stack exchange,提问作者kca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 16:21:49