React登录传参至电影页后出现空白页及解构错误求助
问题分析与解决方案
问题描述
目标是通过Fake API从登录页获取用户数据并传递至MovieList页面,但传递后出现错误,页面空白。错误提示:
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)
附App.js代码:
/* 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;
错误原因与修复步骤
1. 路由跳转组件使用错误
react-router-dom中,路由跳转需要用<Navigate>组件,而非直接嵌套<Route>。原代码里的<Route to="/movies" />是无效写法,会导致路由逻辑混乱,甚至可能在user未正确赋值时就跳转到MovieList,引发user为null的解构错误。
2. 未登录状态下的跳转逻辑错误
/movies路由的else分支设置为跳转到/movies,会触发无限循环,最终导致页面空白。正确逻辑应该是跳转到登录页(/)。
3. useState异步更新导致的user为空
setLoggedIn和setUser是异步操作,即使loggedIn设为true,user可能还未完成更新,此时渲染MovieList会传入null的user,触发解构错误。
4. 缺失fetchUsers函数实现
原代码调用了fetchUsers但未定义,会导致登录逻辑失败,user始终为null。
修正后的完整代码
/* eslint-disable no-unused-vars */ /* eslint-disable no-undef */ // App.js import React, { useState } from 'react'; import { BrowserRouter as Router, Route, Routes, Navigate} from 'react-router-dom'; // 导入Navigate组件 import Login from './components/Login'; import MovieList from './components/MovieList'; // 实现Fake API的fetchUsers函数 const fetchUsers = async () => { // 模拟从API获取用户数据,可替换为真实API请求 return new Promise(resolve => { setTimeout(() => { resolve([ { id: 1, username: "testuser", password: "testpass", loggedIn: true } // 假设用户数据包含loggedIn字段 ]); }, 500); }); }; const App = () => { const [loggedIn, setLoggedIn] = useState(false); const [user, setUser] = useState(null); const handleLogin = async (username, password) => { 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 ? <Navigate to="/movies" /> : <Login onLogin={handleLogin} />} /> {/* MovieList page - 同时判断loggedIn和user是否存在,避免异步更新导致的null问题 */} <Route path="/movies" element={loggedIn && user ? <MovieList user={user} onLogout={handleLogout} /> : <Navigate to="/" />} /> </Routes> </Router> ); }; export default App;
额外建议:MovieList组件内的空值保护
即使在App层做了判断,也建议在MovieList组件内添加空值检查,避免类似错误:
// MovieList.js示例 const MovieList = ({ user, onLogout }) => { // 空值检查,避免user为null时出错 if (!user) return <div>Loading...</div>; // 安全解构user属性 const { loggedIn, username } = user; return ( <div> <h1>Welcome {username}</h1> <button onClick={onLogout}>Logout</button> {/* 电影列表内容 */} </div> ); }; export default MovieList;
内容的提问来源于stack exchange,提问作者Bekir Akay
相关产品推荐
相关产品推荐

