MERN栈CRUD应用白屏问题:刷新时UI短暂显示后消失
MERN栈CRUD应用白屏问题排查与修复
我使用MERN栈开发基础CRUD应用,目前遇到UI白屏问题:页面加载后显示白屏,刷新时UI会短暂出现后又变回白屏,控制台基本无报错信息,预期实现学生信息的增删改查功能。
相关代码
App.jsx
import React, { useState, useEffect } from 'react'; import axios from 'axios'; const App = () => { const [students, setStudents] = useState([]); const [newStudentId, setNewStudentId] = useState(''); const [newStudentName, setNewStudentName] = useState(''); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); useEffect(() => { setLoading(true); axios.get('/students') .then(res => { setStudents(res.data); setLoading(false); }) .catch(err => { setError(err.message); setLoading(false); }); }, []); const addStudent = async () => { try { setLoading(true); const response = await axios.post('/students', { studentId: newStudentId, name: newStudentName }); setStudents([...students, response.data]); setLoading(false); setNewStudentId(''); setNewStudentName(''); } catch (err) { setError(err.message); setLoading(false); } }; const deleteStudent = async (studentId) => { try { setLoading(true); await axios.delete(`/students/${studentId}`); setStudents(students.filter(student => student.studentId !== studentId)); setLoading(false); } catch (err) { setError(err.message); setLoading(false); } }; return ( <div> <h1>Student Management System</h1> <div> <h2>Add Student</h2> <form onSubmit={e => { e.preventDefault(); addStudent(); }}> <label> Student ID: <input type="text" value={newStudentId} onChange={e => setNewStudentId(e.target.value)} required /> </label> <label> Name: <input type="text" value={newStudentName} onChange={e => setNewStudentName(e.target.value)} required /> </label> <button type="submit">Add</button> </form> </div> <div> <h2>Student List</h2> {loading && <p>Loading...</p>} {error && <p>Error: {error}</p>} <ul> {students.map(student => ( <li key={student.studentId}> {student.studentId}: {student.name} <button onClick={() => deleteStudent(student.studentId)}>Delete</button> </li> ))} </ul> </div> </div> ); }; export default App;
main.jsx
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; ReactDOM.render(<App />, document.getElementById('root'));
index.js(后端)
// Import required modules const express = require('express'); const mongoose = require('mongoose'); // Create Express app const app = express(); // Connect to MongoDB mongoose.connect('mongodb://127.0.0.1:27017/students', { useNewUrlParser: true, useUnifiedTopology: true }); const db = mongoose.connection; db.on('error', console.error.bind(console, 'connection error:')); db.once('open', function() { console.log("Connected to MongoDB"); }); // Define a schema for the data const studentSchema = new mongoose.Schema({ studentId: String, name: String }); const Student = mongoose.model('students', studentSchema); // Middleware for JSON parsing app.use(express.json()); // Create a new student app.post('/students', async (req, res) => { try { const newStudent = new Student({ studentId: req.body.studentId, name: req.body.name }); await newStudent.save(); res.status(201).json(newStudent); } catch (err) { res.status(400).json({ message: err.message }); } }); // Get all students app.get('/students', async (req, res) => { try { const students = await Student.find(); res.json(students); } catch (err) { res.status(500).json({ message: err.message }); } }); // Get a single student by studentId app.get('/students/:studentId', getStudent, (req, res) => { res.json(res.student); }); // Update a student by studentId app.patch('/students/:studentId', getStudent, async (req, res) => { if (req.body.name != null) { res.student.name = req.body.name; } try { const updatedStudent = await res.student.save(); res.json(updatedStudent); } catch (err) { res.status(400).json({ message: err.message }); } }); // Delete a student by studentId app.delete('/students/:studentId', getStudent, async (req, res) => { try { await res.student.remove(); res.json({ message: 'Deleted student' }); } catch (err) { res.status(500).json({ message: err.message }); } }); // Middleware to get a student by studentId async function getStudent(req, res, next) { let student; try { student = await Student.findOne({ studentId: req.params.studentId }); if (student == null) { return res.status(404).json({ message: 'Cannot find student' }); } } catch (err) { return res.status(500).json({ message: err.message }); } res.student = student; next(); } // Start the server const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); });
问题根源与修复方案
1. 端口冲突与代理配置缺失
Express后端默认运行在3000端口,而React开发服务器默认也使用3000端口,导致端口冲突;同时前端请求/students时,没有代理到后端服务,请求失败后引发组件渲染异常。
- 修复步骤:
- 修改后端端口:在
index.js中将const PORT = process.env.PORT || 3000;改为const PORT = process.env.PORT || 5000; - 添加React代理:在React项目的
package.json中新增"proxy": "http://localhost:5000",让前端请求自动转发到后端服务
- 修改后端端口:在
2. React渲染API过时
React 18+版本已废弃ReactDOM.render,改用createRoot,旧API可能导致渲染不稳定,出现白屏。
- 修复后的
main.jsx:
import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<App />);
3. 错误日志缺失
原代码中错误仅存入状态,未在控制台打印,不利于排查问题。
- 修改
App.jsx中useEffect的catch块:
.catch(err => { console.error('获取学生数据失败:', err); setError(err.message); setLoading(false); });
4. 数据库连接验证
确保本地MongoDB服务已启动,连接字符串mongodb://127.0.0.1:27017/students正确,避免后端接口因数据库连接失败报错。
内容的提问来源于stack exchange,提问作者nihaanth reddy
相关产品推荐
相关产品推荐

