【问题标题】:React conditional rendering not triggering?反应条件渲染不触发?
【发布时间】:2025-12-31 10:25:11
【问题描述】:

我正在尝试通过 useContext 和条件渲染更改导航栏和路由器的内容。 这是我的 App.js:


import "./App.css";
import axios from "axios";
import { AuthContextProvider } from "./context/AuthContext";
import MyRouter from "./MyRouter";

axios.defaults.withCredentials = true;

function App() {
  return (
    <AuthContextProvider>
      <MyRouter />
    </AuthContextProvider>
  );
}

export default App; 

这是我的路由器:

import React, { useContext } from "react";
import AuthContext from "./context/AuthContext";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Redirect,
} from "react-router-dom";
import MyNavBar from "./components/MyNavbar";
import "./App.css";
import Home from "./components/pages/Home";
import AboutUs from "./components/pages/AboutUs";
import Register from "./components/pages/Register";
import MyFooter from "./components/MyFooter";
import login from "./components/pages/login";
import ProfilePage from "./components/pages/ProfilePage";
function MyRouter() {
  const { loggedIn } = useContext(AuthContext);
  return (
    <Router>
      <MyNavBar />
      <Switch>
        <Route exact path="/" component={Home} />
        <Route exact path="/about-us" component={AboutUs} />
        {loggedIn === false && (
          <>
            <Route exact path="/register" component={Register} />
            <Route exact path="/login" component={login} />
          </>
        )}
        {loggedIn === true && (
          <>
            <Route exact path="/profile" component={ProfilePage} />
          </>
        )}

        <Redirect to="404" />
      </Switch>
      <MyFooter />
    </Router>
  );
}

export default MyRouter;

我的导航栏的条件渲染与路由器的工作方式相同。我的问题是条件渲染片段都不起作用。例如,当我的应用程序启动时,用户未登录并且“loggedIn”值为 false。使用这种逻辑,“注册”和“登录”路由应该可以访问,但它们不是。任何建议或帮助将不胜感激,因为我对使用 React 很陌生。

Here is a screenshot of my console upon loading the application

这是我的“AuthContext”:

const AuthContext = createContext();
function AuthContextProvider(props) {
  const [loggedIn, setLoggedIn] = useState(undefined);
  async function getLoggedIn() {
    const loggedInRes = await axios.get(
      "http://localhost:5000/api/users/loggedIn"
    );
    setLoggedIn(loggedInRes.data);
  }

  useEffect(() => {
    getLoggedIn();
  }, []);
  return (
    <AuthContext.Provider value={{ loggedIn, getLoggedIn }}>
      {props.children}
    </AuthContext.Provider>
  );
}
export default AuthContext;
export { AuthContextProvider };

【问题讨论】:

  • “loggedIn”是否可能不是布尔值,因此它既不是真也不是假,因此,您的条件片段不起作用?
  • 因此,当页面最初加载时,loggedIn 值实际上在更新为正确值之前非常短暂地“未定义”。您认为这可能是问题所在吗?
  • 我认为只有在loggedIn 未定义时才会出现问题。它的新值是布尔值吗?
  • 是的,新值是一个布尔值,如果找到有效令牌则为 true,否则为 false。它通过“AuthContext”中的异步函数进行更新。
  • 你确定吗?如果是这种情况,我不明白为什么你的代码不起作用。

标签: javascript reactjs react-router-dom


【解决方案1】:

感谢大家的帮助,我学到了很多关于 ProtectedRoute 概念的知识。我的问题来自我的导航栏组件。我没有将我的变量声明为对象,而是声明了类似的登录 const loggedIn = useContext(AuthContext); 一旦我将其更改为,我的所有错误都已解决 const { loggedIn } = useContext(AuthContext);

【讨论】:

    【解决方案2】:

    已编辑:

    您可以创建一个 ProtectedRoute 来根据您的条件路由您的组件,而不是在主路由中使用您的条件。

        import React, { useEffect } from "react";
        import { Route, Redirect, useHistory } from "react-router-dom";
        const ProtectedRoute = ({ component: Component, ...rest }) => {
            const { loggedIn } = useContext(AuthContext);
            return (
                <Route
                    {...rest}
                    render={(props) =>
                        loggedIn() ? (
                            <Component {...props} />
                        ) : (
                            <Redirect to='/login' />
                        )
                    }
                />
            );
        };
    export default ProtectedRoute;
    
    • 在您的组件中,您可以通过以下方式更改您的逻辑:
            <ProtectedRoute exact path="/" component={Home} />
            <ProtectedRoute exact path="/about-us" component={AboutUs}/> 
           
            <Route exact path="/register" component={Register} />
            <Route exact path="/login" component={login} />
     
            <ProtectedRoute exact path="/profile" component={ProfilePage} />
           
    

    这意味着如果你想保护一个路由,你应该使用 ProtectedRoute 路由它,否则是经典的反应路由。

    您可以阅读有关 ProtectedRoute 概念 here

    【讨论】:

    • 这不会自动重定向用户吗?我不认为这是作者想要的行为。
    • 是的,你是对的。我没有看到作者使用 Route 选项。他/她需要一条受保护的路线。我会编辑答案。感谢警告