You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 18:14:59