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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 21:37:44