I am making a chat app with React 18 and Firebase 9.
The chat route - which is the root app - is supposed to be accessible only after authentication.
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=>
{children}
</AuthContext.Provider>
);
};
I use the AuthContextProvider in index.js:
import { AuthContextProvider } from './contexts/AuthContext';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<AuthContextProvider>
<React.StrictMode>
<App />
</React.StrictMode>
</AuthContextProvider>
);
reportWebVitals();
The Chrome console throws this error from App.js
:
Uncaught ReferenceError: ProtectedRoute is not defined
What am I doing wrong?
UPDATE
This version of App.js throws a 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} />
);
}
from What causes the failure to protect a route in this React.js app?
No comments:
Post a Comment