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

React Router项目中点击浏览器后退按钮Div仍不可见的问题

问题:浏览器后退后Main组件内容无法自动恢复显示

我在App.jsx中使用react-router,将Main作为父组件配置嵌套路由,子路由对应Login和SignUp组件。为解决<Outlet>内容与Main组件原有内容重叠的问题,我在Main.jsx中给登录、注册按钮绑定了handleClick函数,通过useState控制为标题和按钮区域的div添加invisible类(设置display:none),隐藏这些区域以仅显示<Outlet>内容。但点击浏览器后退按钮回到根路由"/"时,这些隐藏的div依然处于不可见状态,必须刷新页面才能恢复显示。

相关代码

App.jsx

import React, { useState } from "react";
import Main from "./Main";
import SignUp from "./SignUp";
import Login from "./Login";
import Home from "./Home";
import {  createBrowserRouter, createRoutesFromElements, Route, RouterProvider,} from "react-router-dom";

const router = createBrowserRouter(
  createRoutesFromElements(
    <Route path="/" element={<Main />}>
      <Route path="login" element={<Login />} />
      <Route path="signup" element={<SignUp />} />
    </Route>
  )
);

function App() {
  return <RouterProvider router={router} />;
}

export default App;

Main.jsx

import React, { useState } from "react";
import Button from "./Button";
import { NavLink, Outlet } from "react-router-dom";

function Main() {
  const [isVisible, setIsVisible] = useState(true);

  const handleClick = () => {
    setIsVisible(false);
  };

  return (
    <div className="main-div">
      <div className={`main-heading-div ${isVisible ? "" : "invisible"}`}>
        <p className="main-heading">
          Welcome to <span>The Book Keeper</span>
        </p>
        <p>Your Personal Library, Perfectly Organized</p>
      </div>

      <div className={`button-div ${isVisible ? "" : "invisible"}`}>
        <NavLink to="/login">
          <Button text="Log in" name="main-login" onClick={handleClick} />
        </NavLink>
        <NavLink to="/signup">
          <Button text="Sign Up" name="main-signup" onClick={handleClick} />
        </NavLink>
      </div>

      <Outlet />
    </div>
  );
}

export default Main;

解决方案

问题根源在于useState的状态不会随着路由后退自动重置,组件未重新渲染时状态会保持之前的false值。推荐以下两种解决方式:

方式一:监听路由变化重置状态

通过useLocation获取当前路由,用useEffect监听路径变化,当回到根路由时恢复显示状态:

import React, { useState, useEffect } from "react";
import Button from "./Button";
import { NavLink, Outlet, useLocation } from "react-router-dom";

function Main() {
  const [isVisible, setIsVisible] = useState(true);
  const location = useLocation();

  useEffect(() => {
    // 路由回到根路径时,恢复显示状态
    if (location.pathname === "/") {
      setIsVisible(true);
    }
  }, [location.pathname]);

  const handleClick = () => {
    setIsVisible(false);
  };

  return (
    <div className="main-div">
      <div className={`main-heading-div ${isVisible ? "" : "invisible"}`}>
        <p className="main-heading">
          Welcome to <span>The Book Keeper</span>
        </p>
        <p>Your Personal Library, Perfectly Organized</p>
      </div>

      <div className={`button-div ${isVisible ? "" : "invisible"}`}>
        <NavLink to="/login">
          <Button text="Log in" name="main-login" onClick={handleClick} />
        </NavLink>
        <NavLink to="/signup">
          <Button text="Sign Up" name="main-signup" onClick={handleClick} />
        </NavLink>
      </div>

      <Outlet />
    </div>
  );
}

export default Main;

方式二:直接根据路由路径判断显示状态

无需额外维护useState,直接通过当前路由路径决定是否显示内容,更符合react-router的设计逻辑:

import React from "react";
import Button from "./Button";
import { NavLink, Outlet, useLocation } from "react-router-dom";

function Main() {
  const location = useLocation();
  // 仅在根路径时显示标题和按钮区域
  const isVisible = location.pathname === "/";

  return (
    <div className="main-div">
      <div className={`main-heading-div ${isVisible ? "" : "invisible"}`}>
        <p className="main-heading">
          Welcome to <span>The Book Keeper</span>
        </p>
        <p>Your Personal Library, Perfectly Organized</p>
      </div>

      <div className={`button-div ${isVisible ? "" : "invisible"}`}>
        <NavLink to="/login">
          <Button text="Log in" name="main-login" />
        </NavLink>
        <NavLink to="/signup">
          <Button text="Sign Up" name="main-signup" />
        </NavLink>
      </div>

      <Outlet />
    </div>
  );
}

export default Main;

这种方式下,路由变化时组件会自动根据路径更新显示状态,无需手动处理点击事件和状态重置,彻底避免了状态不同步的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 21:37:44