是什么原因导致此 React.js 应用程序中的路由无法保护?

2024-04-13

我正在使用 React 18 和 Firebase 9 制作一个聊天应用程序。

聊天路由(即根应用程序)应该只有在身份验证后才能访问。

In App.js I have:

import { useContext } from 'react';
import {
  createBrowserRouter,
  createRoutesFromElements,
  Route,
  RouterProvider,
  Navigate
} from 'react-router-dom';
import RootLayout from './layouts/RootLayout';
import AuthLayout from './layouts/AuthLayout';
import Chat from './pages/Chat';
import Register from './pages/Register';
import Login from './pages/Login';
import { AuthContext } from './contexts/AuthContext';

const router = createBrowserRouter(
  createRoutesFromElements(
    <Route path="/" element={<RootLayout />}>
      <Route index
        element={
          <ProtectedRoute>
            <Chat />
          </ProtectedRoute>
        } />

      <Route path="auth" element={<AuthLayout />}>
        <Route path="register" element={<Register />} />
        <Route path="login" element={<Login />} />
      </Route>
    </Route>
  )
);

function App() {
  const { currentUser } = useContext(AuthContext);

  const ProtectedRoute = ({ children }) => {
    if (!currentUser) {
      return <Navigate to="/auth/login" />;
    }
    return children
  };

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

export default App;

In src\contexts\AuthContext.js I have:

import { createContext, useEffect, useState } from "react";
import { auth } from "../firebaseConfig";
import { onAuthStateChanged } from "firebase/auth";

export const AuthContext = createContext();
export const AuthContextProvider = ({ children }) => {
  const [currentUser, setCurrentUser] = useState({});

  useEffect(() => {
    const unSubscribe = onAuthStateChanged(auth, (user) => {
      setCurrentUser(user);
      console.log(user);
    });

    return () => {
      unSubscribe();
    };
  }, []);

  return (
    <AuthContext.Provider value={{ currentUser }}>
      {children}
    </AuthContext.Provider>
  );
};

我在index.js中使用AuthContextProvider:

import { AuthContextProvider } from './contexts/AuthContext';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <AuthContextProvider>
    <React.StrictMode>
      <App />
    </React.StrictMode>
  </AuthContextProvider>
);
reportWebVitals();

Chrome 控制台抛出此错误App.js:

Uncaught ReferenceError: ProtectedRoute is not defined

我究竟做错了什么?

UPDATE

这个版本的 App.js 抛出了一个React Hook "useContext" cannot be called at the top level error:

const { currentUser } = useContext(AuthContext);

const ProtectedRoute = ({ children, currentUser }) => {
  if (!currentUser) {
    return <Navigate to="/auth/login" />;
  }
  return children
};

const router = createBrowserRouter(
  createRoutesFromElements(
    <Route path="/" element={<RootLayout />}>
      <Route index
        element={
          <ProtectedRoute currentUser={ currentUser }>
            <Chat />
          </ProtectedRoute>
        } />

      <Route path="auth" element={<AuthLayout />}>
        <Route path="register" element={<Register />} />
        <Route path="login" element={<Login />} />
      </Route>
    </Route>
  )
);

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

在 App.js 的更新版本中,您进行了一些改进来处理 useContext 问题并将 currentUser 传递给 ProtectedRoute。但是,您仍然遇到 ProtectedRoute 未定义的问题。

让我们解决这个问题并进行必要的调整。 将 ProtectedRoute 函数移到 App 组件之外,以便在使用它之前对其进行定义。

const ProtectedRoute = ({ children, currentUser }) => {
  if (!currentUser) {
    return <Navigate to="/auth/login" />;
  }
  return children;
};

function App() {
  const { currentUser } = useContext(AuthContext);

  const router = createBrowserRouter(
    createRoutesFromElements(
      <Route path="/" element={<RootLayout />}>
        <Route
          index
          element={<ProtectedRoute currentUser={currentUser}><Chat /></ProtectedRoute>}
        />
        <Route path="auth" element={<AuthLayout />}>
          <Route path="register" element={<Register />} />
          <Route path="login" element={<Login />} />
        </Route>
      </Route>
    )
  );

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

通过将 ProtectedRoute 移至 App 之外,它将在 JSX 中使用之前进行定义。

您现在在更新的代码中将 currentUser 作为 prop 传递给 ProtectedRoute。这允许 ProtectedRoute 访问 currentUser 并确定用户是否经过身份验证。

通过这些调整,错误应该得到解决,并且 ProtectedRoute 组件现在应该在您的 React 应用程序中定义并正常运行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是什么原因导致此 React.js 应用程序中的路由无法保护? 的相关文章

  • iOS 11 浏览器图像错误

    在 iOS 11 中滚动页面时出现以下错误 在 Firefox Safari 和 Chrome 中 在 Android 设备中 不会发生该错误 这些是背景图像 我不知道这是否是导致错误的原因 图 2 显示了图像在 Android 中的用途和
  • 从 x,y 屏幕空间坐标查找 2D 等距网格上的列、行(将方程转换为函数)

    我试图在屏幕空间点 x y 的二维等距网格中找到行 列 现在我几乎知道我需要做什么 即找到上图中红色向量的长度 然后将其与表示网格边界的向量的长度 由黑色向量表示 进行比较 现在我在数学堆栈交换中寻求帮助 以获得用于计算点 x y 与黑色边
  • 在浏览器中语音聊天? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我们正在寻求建立一个小组 voice 使用服务器上的node js 在浏览器中聊天 这可能吗 如果您希望您的解决方案是基于服务器端和客
  • 未捕获的引用错误:myFunction 未定义[重复]

    这个问题在这里已经有答案了 这到底是怎么回事 http jsfiddle net sVT54 http jsfiddle net sVT54
  • 将音频与视频流合并 Node.js

    我正在创建 YouTube 视频下载器并且正在使用ytdl core库 它无法下载带有音频的高质量视频 因为 youtube 将其放在另一个文件中 但我需要将其全部下载到一个文件中 我已经这样做了 app get download asyn
  • 禁用 JavaScript 中的右键单击

    当我尝试禁用右键单击时 它不起作用 我尝试使用下面的代码 document onclick function e console log e button if e button 2 e preventDefault return fals
  • 使用模态表单 ajax 超出 HTMLFormElement.toString 的最大调用堆栈大小

    我想使用模态窗口中的 ajax 请求提交表单 单击此链接可打开该模式 a class btn btn primary i class fa fa edit i Write a review a 模态窗口 div class modal fa
  • ElectronJS ReferenceError:导航器未定义

    我正在尝试在电子上制作自定义标题栏 但是当我启动我的应用程序时 我遇到了 ReferenceError 导航器未定义 问题 请帮忙 这是我的 main js 中的代码片段 My Codes https i stack imgur com c
  • iframe 重新加载按钮

    我浏览了很多网站 但似乎没有一个能正常工作 或者我不明白它们 我想要一个刷新某个 iframe 的简单按钮 该按钮将位于父页面上 并且 iframe 名称为 Right 有很多方法可以做到这一点 假设这个iframe markup 我们可以
  • 用数组反向查找对象

    假设我有一个这样的对象 resourceMap a 0 1 2 3 4 5 6 7 8 9 10 b 11 12 c 21 23 d 54 55 56 57 510 确定是否的最佳方法是什么resourceId 21将会 c 我们不知道钥匙
  • jQuery 选择器:为什么 $("#id").find("p") 比 $("#id p") 更快

    该页面的作者 http 24ways org 2011 your jquery now with less suck http 24ways org 2011 your jquery now with less suck断言 jQuery
  • 如何将 Browserify 与外部依赖项一起使用?

    我正在尝试慢慢地将 Browserify 引入我的网站 但我不想重写所有 js 也不希望 jquery 和其他库的重复实例与我的 Browserify 版本捆绑在一起 如果我构建将 jquery 列为外部依赖项的模块 那么如何将其指向我的全
  • 有关于 PHP 中的 V8JS 的文档吗?

    有没有关于V8JS的文档 我是否只需要标准 PHP 或一些扩展即可使用 V8JS 我将非常感谢有关 PHP 中的 V8JS 的任何信息 要求 PHP 5 3 3 和 V8 库和标头安装在正确的路径中 Install http www php
  • window.showModalDialog 的等效跨浏览器解决方案是什么?

    window showModalDialog 的等效跨浏览器解决方案有哪些 showModalDialog 在 IE 和 FF 3 中引入 我个人认为没有 但是有很多 UI 工具包提供了这样的功能 例如jQuery UI http jque
  • 加载另一个 JS 脚本后加载

    这是我的代码 very big js file lots of html stuff 问题是 这些是异步加载的 有没有办法等待第二个脚本直到第一个脚本加载 如果您使用 jQuery 有一个非常简单的方法可以通过获取脚本 https api
  • 需要js、d3 和 nvd3 集成

    我面临整合的问题要求 questions tagged requirejs with d3 questions tagged d3 and nvd3 questions tagged nvd3 我找到了一个使用 require 的简单解决方
  • 如何获取使用 .map 渲染的第一个元素的 ref?

    我需要在几行中显示视频 卡片 的缩略图 并重点关注第一个缩略图 我使用嵌套地图进行了显示 该代码基本上迭代视频数组并返回多行视频 我们如何关注第一个渲染的元素 我认为我们需要获得第一个要聚焦的元素的引用 但是我们如何在这里设置 ref 并在
  • 在javascript中动态生成行?

    我是 javascript 新手 我想在按下 Tab 时动态生成行 并希望获取在动态生成的行中输入的值 以便我可以在 servlet 代码中使用这些值 这是我的html
  • 尝试将 Firebase 版本回滚到 2.X

    我最近更新到了新的 Firebase 3 但不幸的是 据我所知 它目前不支持 Geofire 查询 这对我的应用程序很重要 我已经将应用程序中的其他所有内容都转为使用 Firebase 2 但是当我尝试时要将我的应用程序部署到 fireba
  • 如何更改订阅值?使用 rxJS

    我正在创建一个计时器 需要你的帮助 我刚刚学习 Angular 和 rxJS 对此我有一些疑问 我正在创建一个具有启动 停止 暂停 重置功能的计时器 并且 btn Reset 必须将我的计时器 暂停 到 300 毫秒 怎么做 D 我的启动定

随机推荐