My goal is to control the user’s data from the login page via the fakeAPI and pass it to the movies page, but after passing the user information, these errors appear before a blank page comes up.
/* eslint-disable no-unused-vars */
/* eslint-disable no-undef */
// App.js
import React, { useState } from 'react';
import { BrowserRouter as Router, Route, Routes} from 'react-router-dom';
import Login from './components/Login';
import MovieList from './components/MovieList';
const App = () => {
const [loggedIn, setLoggedIn] = useState(false);
const [user, setUser] = useState(null);
const handleLogin = async (username, password) => {
// Simulate user authentication using the fake API
const users = await fetchUsers();
const matchedUser = users.find(
(user) => user.username === username && user.password === password
);
if (matchedUser) {
setLoggedIn(true);
setUser(matchedUser);
} else {
alert('Invalid credentials. Please try again.');
}
};
const handleLogout = () => {
setLoggedIn(false);
setUser(null);
};
return (
<Router>
<Routes>
{/* Login page */}
<Route path="/" element={loggedIn ? <Route to="/movies" /> : <Login onLogin={handleLogin} />} />
{/* MovieList page */}
<Route path="/movies" element={loggedIn ? <MovieList user={user} onLogout={handleLogout} /> : <Route to="/movies" />} />
</Routes>
</Router>
);
};
export default App;
I dont understand what those mean.
Error image:
Cannot destructure property ‘loggedIn’ of ‘user’ as it is null.
TypeError: Cannot destructure property ‘loggedIn’ of ‘user’ as it is null.
at MovieList (http://localhost:3000/static/js/bundle.js:414:5)
at renderWithHooks (http://localhost:3000/static/js/bundle.js:25955:22)
at mountIndeterminateComponent (http://localhost:3000/static/js/bundle.js:29241:17)
at beginWork (http://localhost:3000/static/js/bundle.js:30537:20)
at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:15547:18)
at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:15591:20)
at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:15648:35)
at beginWork$1 (http://localhost:3000/static/js/bundle.js:35522:11)
at performUnitOfWork (http://localhost:3000/static/js/bundle.js:34769:16)
at workLoopSync (http://localhost:3000/static/js/bundle.js:34692:9)
2
Answers
Here’s how you should structure your routes using the Routes and Route components:
it looks like you want to redirect a user if they’re not logged in. This is possible, but your implementation is flawed. When you write
<Component />
the component is rendered when the containing function is called.When you wrote
<Route path="/" element={loggedIn ? <Route to="/movies" /> : <Login onLogin={handleLogin} />} />
<Route to="/movies" />
is rendered, hence the error you’re receiving.You should leverage the
<Navigate />
component, the documentation has a similar example to your code: https://reactrouter.com/en/main/components/navigateWhile this is a misuse of react-router, I’ve seen a lot of engineers thrown off because they did not understand the error. The real issue here is that you did not realize you were rendering the
Route
component as specified in the error.This should work:
<Route path="/" element={loggedIn ? <Navigate to="/movies" /> : <Login onLogin={handleLogin} />} />
Updated error
This line is throwing the error:
<Route path="/movies" element={loggedIn ? <MovieList user={user} onLogout={handleLogout} /> : <Route to="/movies" />} />
loggedIn
is true butuser
is null. In general, it’s important to know when a value is derived.loggedIn
indicates whether there is a user, so derive its value fromuser
.