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

React路由跳转时Navbar组件admin状态被重置如何解决

问题根因

  1. 你当前的Navbar组件大概率是在每个页面(Team、Members等)内部单独引入渲染,路由切换时页面组件会卸载重建,连带Navbar也会重新挂载,内部的admin、passedData等局部状态自然会被重置。
  2. useEffect的依赖数组仅设置了user,当data props、路由参数发生变化时,不会重新触发admin权限校验逻辑,就算数据正确传递也不会更新admin状态。
  3. 跳转Medlemar路由时你把passedData存在了路由state中,但现有Navbar没有从路由state取值的逻辑,跳转后passedData为空,自然不会触发admin查询。

解决方案

步骤1:调整路由结构,避免Navbar重复挂载

把Navbar移到Router内部、Switch外层,所有路由共享同一个Navbar实例,路由切换时不会被卸载,状态自然保留:

function App() {
  return (
    <>
      <Router>
        {/* Navbar放在这里,全局唯一实例 */}
        <Navbar />
        <Switch>
          <Route path="/" exact component={Home} />
          <Route path="/logg-inn" component={Login} />
          <Route path="/lag/:id" exact component={Team} />
          <Route path="/profil" component={Profile} />
          <Route path="/registrer-deg" component={Signup} />
          <Route path="/lag" exact component={Teams} />
          <Route path="/lag/:id/innstillingar" exact component={TeamSettings} />
          <Route path="/lag/:id/betaling" exact component={Payment} />
          <Route path="/lag/:id/arrangement" exact component={Events} />
          <Route path="/lag/:id/admin/medlemar" component={Members} />
        </Switch>
      </Router>
    </>
  );
}

步骤2:修正Navbar逻辑,补全触发条件

调整Navbar的依赖和取值逻辑,支持从路由state取数据,数据变化时自动重新校验admin权限:

import { useLocation } from 'react-router-dom'

function Navbar({ data }) {
  const [user, setUser] = useState(null)
  const [admin, setAdmin] = useState(false)
  const location = useLocation()

  // 用户登录状态监听单独抽离,只执行一次,避免重复监听
  useEffect(() => {
    const unsubscribe = firebase.auth().onAuthStateChanged((user) => {
      setUser(user)
    })
    // 组件卸载时取消监听,避免内存泄漏
    return () => unsubscribe()
  }, [])

  // admin权限校验逻辑,依赖变化时自动重新执行
  useEffect(() => {
    // 优先取路由state的传递数据,没有就取props传入的data
    const currentData = location.state?.passedData || data
    // 没有登录或者没有团队ID时直接置为非管理员
    if (!user || !currentData?.teamID) {
      setAdmin(false)
      return
    }
    // 查询管理员权限
    firebase.firestore().collection('teams').doc(currentData.teamID).collection('members').doc(user.uid).get().then((snapshot) => {
      const administrator = snapshot.get('role')
      setAdmin(administrator === 'admin')
    })
  }, [user, data, location.state])

  // 原有return的JSX逻辑保持不变即可
  return (
    <nav className='navbar'>
      <ul className='nav-menu-items'>
        <li className="nav-text">
          <Link to="/">
            <AiIcons.AiFillDashboard size="1.4em" className="icon" />
            <span>Dashboard</span>
          </Link>
        </li>
        <li className="nav-text">
          <Link to="/lag">
            <AiIcons.AiOutlineTeam size="1.4em" className="icon" />
            <span>Lag</span>
          </Link>
        </li>
        <li className="nav-text">
          <Link to="/profil">
            <BsIcons.BsPerson size="1.4em" className="icon" />
            <span>Profil</span>
          </Link>
        </li>
        <li className="nav-text">
          <Link to="/betaling">
            <GiIcons.GiPayMoney size="1.4em" className="icon" />
            <span>Betaling</span>
          </Link>
        </li>
        </ul>
        {admin ? 
          <>
          <span className="admin-text">Admin</span>
          <div className="navbar-divider"></div>
            <ul className="nav-menu-items">
              <li className="nav-text">
                <Link to={{
                  pathname: `/lag/${data.teamID}/admin/medlemar`,
                  state: {
                    passedData: data,
                  }
                }}>
                  <BsIcons.BsPeopleFill className="icon" size="1.4em" />
                  <span>Medlemar</span>
                </Link>
              </li>
            </ul>
            </>
        :
          null
        }
    </nav>
  )
}

可选长效优化

如果应用规模较大,建议用React Context、Zustand这类状态管理工具把用户信息、admin权限全局存储,所有组件可以直接消费,不会因为组件挂载卸载丢失状态,也不用重复查询权限。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 04:45:03