我正在try 在REACTIV18中设置路由,将某些页面限制为只允许登录的用户访问.我似乎不能让return语句中的函数工作.LoginRegister工作正常.如果我将另一个组件放在函数之外,与LoginRegister相同的级别,它也可以很好地工作.但是当页面加载时,它应该达到localhost/,看到没有令牌,然后路由到/login.现在,它只停留在localhost/,并显示一个空白页面.控制台中的警告是:"没有与位置匹配的路由‘/’".这是正确的,因为路径为"/"的组件在AppViews中,应该受到限制.但它不会将用户移动到‘/登录’.为什么不行?我遗漏了什么?

export const MyApp = () => {
  const [token, setTokenState] = useState(localStorage.getItem('token'))

  const setToken = (newToken) => {
    localStorage.setItem('token', newToken)
    setTokenState(newToken)
  }


  return (
    <>
        <Routes>
            { <Route render={() => {
                if (localStorage.getItem("app_token")) {
                    return <>
                        <Route>
                            <AppViews />
                        </Route>
                    </>
                } else {
                    return <Navigate to="/login" />
                }
                }} />
             }
            <Route path="/login" element={<Login />} />
            <Route path="/register" element={<Register />} />         
        </Routes>
    </>
  )
}
 
export default MyApp;

推荐答案

react-router-dom@6中,Route组件没有任何renderprops .换句话说,renderprops 被完全忽略,没有任何效果.所有传送的内容都会在elementprops 上呈现出来.使用三元运算符有条件地呈现重定向或AppViews组件.

export const MyApp = () => {
  const [token, setTokenState] = useState(localStorage.getItem('token'))

  const setToken = (newToken) => {
    localStorage.setItem('token', newToken)
    setTokenState(newToken)
  }

  return (
    <Routes>
      <Route
        path="/*"
        element={localStorage.getItem("app_token")
          ? <AppViews />
          : <Navigate to="/login" replace />
        }
      />
      <Route path="/login" element={<Login />} />
      <Route path="/register" element={<Register />} />         
    </Routes>
  );
}

更传统的做法是创建受保护的路由组件.

示例:

import { Navigate, Outlet } from 'react-router-dom';

const ProtectedRoute = () => {
  const appToken = localStorage.getItem("app_token");

  return appToken
    ? <Outlet />
    : <Navigate to="/login" replace />
};

...

export const MyApp = () => {
  const [token, setTokenState] = useState(localStorage.getItem('token'))

  const setToken = (newToken) => {
    localStorage.setItem('token', newToken)
    setTokenState(newToken)
  }

  return (
    <Routes>
      <Route element={<ProtectedRoute />}>
        <Route path="/*" element={<AppViews />} />
      </Route>
      <Route path="/login" element={<Login />} />
      <Route path="/register" element={<Register />} />         
    </Routes>
  );
}

Reactjs相关问答推荐

如何使用json将购物车数组传递到后台API

条件索引路由

react 路由导航不工作,但手动路由工作

在react.js的条形图中获取错误&unfined是不可迭代的

以下代码是否存在安全问题?

使用`Link`包装`tr`标记会在Next.js中产生水合错误14

在构建或部署Reaction应用程序时出错

GitHub页面未正确显示Reaction应用程序网站

如何使用.Aggregate从多个集合中获取数据,包括使用Mongoose+NextJS的SUM值

根据处于react 状态的数组的名称键,将新对象添加到嵌套的对象数组中

使用experial_useFormState将参数传递给服务器操作

有没有办法在 React Router v6 中的路由匹配上运行一些逻辑/功能?

如何在 React Native 中渲染下面的对象数组?

预期无限重新渲染但没有发生

React useEffect 依赖项

Firebase Storage: 对象不存在图片上传路径错误

带有 webpack 错误多个文件匹配路由名称的 Expo-router.无法Bundle 或部署应用程序

React v6 中的公共和私有路由

react 事件顺序

为什么此代码中的 useState 不更新(文本更新但 id 不更新)?