【问题标题】:State is getting reset when changing route更改路线时状态正在重置
【发布时间】:2021-09-19 16:06:00
【问题描述】:

我的 react 应用中有一个 Navbar 组件。我在Navbar 组件中管理管理状态。当我已经在Lag 路由上并尝试路由到Medlemar 时,导航栏的管理部分会消失。这是因为更改路由时管理员状态正在重置。我怎样才能防止这种情况发生?

导航栏组件:

function Navbar({ data }) {
  const [user, setUser] = useState(null)
  const [admin, setAdmin] = useState(false)
  const [passedData, setData] = useState(undefined)

  useEffect(() => {
    firebase.auth().onAuthStateChanged((user) => {
      setUser(user)
    })

    if (passedData) {
      console.log(passedData)
    } else {
      setData(data)
    }

    if (user) {
      if(passedData !== undefined) {
        firebase.firestore().collection('teams').doc(passedData.teamID).collection('members').doc(user.uid).get().then((snapshot) => {
          const administrator = snapshot.get('role')

          if (administrator === 'admin') {
            setAdmin(true)
          } else {
            setAdmin(false)
          }
        })
      }
    }
  }, [user])

    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>
    )
}

App.js

function App() {
  return (
    <>
      <Router>
        <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>
    </>
  );
}

【问题讨论】:

  • 你在哪里使用导航栏组件?
  • 在每个页面组件中
  • 你应该在一个常见的地方使用 NavBar 组件。也许在您的应用程序文件中。就在路线之前
  • 哦,等等,对不起。我不在登录组件中使用它,也没有在注册组件中使用它。所以不是每个组件
  • 您还可以提升状态并在 App.js 上定义 admin、setAdmin 并将它们作为 props 传递。但是最好只在 App.js 中使用 NavBar

标签: javascript reactjs state react-router-dom


【解决方案1】:

如果您想通过导航栏在路由之间保持状态,那么您应该将其用作包装器组件并用它包装 /lag 路由。

一般来说,最好使用 React Context 或任何其他状态管理库来避免将来出现问题,但我提供的解决方案应该可以工作。

您的 Navbar 组件可以带子项(用于包装目的),并且看起来像这样:

function Navbar({ data, children }) {
    const [user, setUser] = useState(null);
    const [admin, setAdmin] = useState(false);
    const [passedData, setData] = useState(undefined);

    useEffect(() => {
        firebase.auth().onAuthStateChanged((user) => {
            setUser(user);
        });

        if (passedData) {
            console.log(passedData);
        } else {
            setData(data);
        }

        if (user) {
            if (passedData !== undefined) {
                firebase
                    .firestore()
                    .collection('teams')
                    .doc(passedData.teamID)
                    .collection('members')
                    .doc(user.uid)
                    .get()
                    .then((snapshot) => {
                        const administrator = snapshot.get('role');

                        if (administrator === 'admin') {
                            setAdmin(true);
                        } else {
                            setAdmin(false);
                        }
                    });
            }
        }
    }, [user]);

    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}

            {children}
        </nav>
    );
}

然后您的应用将看起来像这样:

function App() {
    return (
      <>
        <Router>
          <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} />
            <Navbar>
            <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} />
            </Navbar>
          </Switch>
        </Router>
      </>
    );
  }

【讨论】:

  • 我不太了解你,请你解释一下。抱歉,我对 React 还是很陌生。
  • 我将在一秒钟内用代码示例编辑我的答案
  • 谢谢,我现在明白了。稍后我会看看它
  • 当然,如果这回答了您的问题,请不要忘记将其标记为答案并点赞
  • 现在,我得到了两个彼此下方的导航栏,例如导航栏中的成员页面。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-10
  • 2018-09-04
  • 2019-10-13
  • 2021-03-04
  • 2020-07-25
  • 2019-08-10
  • 2016-10-21
相关资源
最近更新 更多