React应用加载显示空白,路由从index.js迁移至App.js后故障求助
React应用路由迁移后页面空白问题修复方案
核心问题根因
- 语法错误:App组件没有写
return语句,函数组件必须返回JSX结构才会被正常渲染,缺失return会直接导致渲染报错,页面空白。 - 无限递归死循环:App内部路由配置了根路径
/对应渲染App组件本身,访问首页时会触发App组件无限嵌套渲染,直接导致页面卡死。 - 数据状态隔离:接口请求拿到的lessons数据存在LoadingHOC的内部state中,外部的Lessons组件无法获取到该数据,即便前面的问题修复,首页也无法正常展示课程列表。
- 路由传参方式错误:如果需要给路由组件传递自定义props,react-router v5中不能使用
component属性,要改用render属性才能传入自定义参数。
修复后代码
App.js
import './App.css'; import Lessons from './components/Lessons'; import React,{useEffect,useState} from 'react'; import { Route, BrowserRouter as Router, Switch } from "react-router-dom"; import { ThemeProvider } from "@material-ui/core/styles"; import Header from "./components/Header"; import Footer from "./components/Footer"; import UpdateForm from "./components/UpdateForm"; import Register from "./components/Register"; import CreateLesson from "./components/CreateLesson"; import DeleteLesson from "./components/DeleteLesson"; import Students from "./components/Students"; import Login from "./components/Login"; import theme from "./theme"; function App (){ // 把数据状态提升到App组件,方便传递给子组件 const [appState, setAppState] = useState({ loading: false, lessons: null }); useEffect(() => { setAppState({ loading: true }); const apiUrl = "http://127.0.0.1:8000/api/"; fetch(apiUrl) .then((data) => data.json()) .then((lessons) => { setAppState({ loading: false, lessons: lessons }); }); }, []); // 补上return语句 return ( <ThemeProvider theme={theme}> <Router> <React.StrictMode> {/* 加载状态下显示加载提示 */} {appState.loading && <p style={{ fontSize: "25px" }}>We are waiting for the data to load!...</p>} <Header /> <Switch> <Route exact path="/account/register" component={Register} /> <Route exact path="/account/login" component={Login} /> <Route path="/create/" component={CreateLesson} /> <Route path="/delete/" component={DeleteLesson} /> <Route path="/students" component={Students} /> <Route path="/:id" component={UpdateForm} /> {/* 根路径渲染Lessons组件,传入lessons数据 */} <Route exact path="/" render={(props) => <Lessons {...props} lessons={appState.lessons} />} /> </Switch> <Footer /> </React.StrictMode> </Router> </ThemeProvider> ); } export default App;
其他调整说明
- 原来的
LoadingHOC.js可以不用再单独引入,因为我们已经把加载逻辑和状态提升到了App组件内部,避免状态隔离的问题。 - 如果你要根据当前路由修改Footer的按钮内容,可以在App组件中使用
useLocation钩子获取当前路由信息,然后把对应状态传递给Footer组件即可。 - 检查你的
react-router-dom版本,如果是v6版本,需要把Switch替换为Routes,component/render属性替换为element属性,写法会有差异。
内容的提问来源于stack exchange,提问作者Anat
相关产品推荐
相关产品推荐

