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

MERN栈React Hooks问题:添加筛选后Bus数据无法显示

MERN栈班车列表不显示问题排查与解决

问题概述

在MERN栈项目中添加筛选功能后,页面无法显示Bus数据(数据库中存在该数据且可正常创建新数据),回滚代码后问题依然存在。控制台抛出React Hooks依赖警告:Line 41:6: React Hook useEffect has a missing dependency: 'getBuses'. Either include it or remove the dependency array react-hooks/exhaustive-deps,同时Bus数据未成功从后端传输到前端。

核心问题分析

  1. React闭包与依赖缺失:getBuses函数依赖filters状态,但useEffect使用空依赖数组仅执行一次,导致函数捕获的是初始空filters,后续状态更新无法触发重新请求;ESLint的依赖警告是表象,背后的闭包问题会导致请求逻辑异常。
  2. 后端接口两个关键问题:
    • get-all-buses接口添加了authMiddleware但未验证前端是否携带有效Token,可能导致请求被拦截,数据无法返回;同时接口未使用前端传递的filters参数,等于未实现筛选逻辑。
    • 接口响应存在多处拼写错误(seccess、meggage),会导致前端判断response.data.success时出错,无法正确设置buses状态。
  3. 前端渲染大小写不匹配:MongoDB Schema中status字段默认值为'Yet to Start'(首字母大写),但前端过滤条件使用bus.status === "Yet to start"(start小写),导致过滤后无数据显示。

代码修复方案

前端Home组件修复

import React, { useEffect, useState, useCallback } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { axiosInstance } from '../helpers/axiosInstance';
import { HideLoading, ShowLoading } from '../redux/alertsSlice';
import { Col, Row, message } from 'antd';
import Bus from '../components/Bus';

function Home() {
  const { user } = useSelector(state => state.users)
  const [filters, setFilters] = useState({});
  const dispatch = useDispatch();
  const [buses, setBuses] = useState([]);

  // 用useCallback缓存函数,避免重复创建导致无限循环
  const getBuses = useCallback(async () => {
    const tempFilters = {};
    Object.keys(filters).forEach((key) => {
      if (filters[key]) {
        tempFilters[key] = filters[key];
      }
    })
    try {
      dispatch(ShowLoading())
      const response = await axiosInstance.post(
        "/api/buses/get-all-buses",
        tempFilters
      );
      dispatch(HideLoading());
      if (response.data.success) {
        setBuses(response.data.data);
      } else {
        message.error(response.data.message || '获取班车数据失败');
      }
    } catch (error) {
      dispatch(HideLoading());
      message.error(error.message || '网络请求失败');
    }
  }, [filters, dispatch]); // 声明函数依赖

  useEffect(() => {
    getBuses();
  }, [getBuses]); // 将getBuses加入依赖数组

  // 修复status过滤的大小写匹配问题
  const filteredBuses = buses.filter((bus) => bus.status === "Yet to Start");

  return (
    <div>
      <div className='my-3 card p-2'>
        <Row gutter={10}>
          <Col lg={6} sm={24}>
            <input type='text'
              placeholder='出发地'
              value={filters.from || ''}
              onChange={(e) => setFilters(prev => ({ ...prev, from: e.target.value }))}
            />
          </Col>
          <Col lg={6} sm={24}>
            <input type='text'
              placeholder='目的地'
              value={filters.to || ''}
              onChange={(e) => setFilters(prev => ({ ...prev, to: e.target.value }))}
            />
          </Col>
          <Col lg={6} sm={24}>
            <input type='date'
              placeholder='行程日期'
              value={filters.journeyDate || ''}
              onChange={(e) => setFilters(prev => ({ ...prev, journeyDate: e.target.value }))}
            />
          </Col>
          <Col lg={6} sm={24}>
            <button className='primary-btn' onClick={getBuses}>
              筛选
            </button>
          </Col>
        </Row>
      </div>
      <div>
        <Row gutter={[15, 15]}>
          {filteredBuses.map((bus) => (
            <Col lg={12} xs={24} sm={24} key={bus._id}>
              <Bus bus={bus} />
            </Col>
          ))}
        </Row>
      </div>
    </div>
  )
}

export default Home

后端busesRoute修复

const router = require('express').Router();
const Bus = require("../models/busModel")
const authMiddleware = require("../middlewares/authMiddleware")

// 添加班车
router.post('/add-bus', async (req, res) => {
    try {
        const existingBus = await Bus.findOne({ number: req.body.number })

        if (existingBus) {
            return res.status(200).send({
                success: false, // 修复拼写错误
                message: '班车已存在', // 修复拼写错误
            })
        }
        const newBus = new Bus(req.body);
        await newBus.save();
        return res.status(200).send({
            success: true,
            message: '班车添加成功'
        })
    } catch (error) {
        res.status(500).send({
            success: false,
            message: error.message // 修复拼写错误
        })
    }
});

// 更新班车
router.post("/update-bus", authMiddleware, async (req, res) => {
    try {
        await Bus.findByIdAndUpdate(req.body._id, req.body)
        return res.status(200).send({
            success: true,
            message: '班车更新成功',
        })
    }
    catch (error) {
        res.status(500).send({success: false, message: error.message}) // 修复拼写错误
    }
});

// 删除班车
router.post("/delete-bus", authMiddleware, async (req, res) => {
    try {
        await Bus.findByIdAndDelete(req.body._id)
        return res.status(200).send({
            success: true,
            message: '班车删除成功',
        })
    }
    catch (error) {
        res.status(500).send({success: false, message: error.message}) // 修复拼写错误
    }
});

// 获取所有班车:若为公开页面则移除authMiddleware,需登录则保留
router.post("/get-all-buses", /* authMiddleware, */ async (req, res) => {
    try {
        const filters = req.body;
        // 构建有效查询条件
        const query = {};
        if (filters.from) query.from = filters.from;
        if (filters.to) query.to = filters.to;
        if (filters.journeyDate) query.journeyDate = filters.journeyDate;
        
        const buses = await Bus.find(query); // 使用筛选条件查询
        return res.status(200).send({
            success: true,
            message: "班车数据获取成功",
            data: buses,
        })
    } catch (error) {
        res.status(500).send({
            success: false,
            message: error.message
        })
    };
})

// 根据ID获取班车
router.post("/get-bus-by-id", authMiddleware, async (req, res) => {
    try {
        const bus = await Bus.findById(req.body._id);
        return res.status(200).send({
            success: true,
            message: "班车数据获取成功",
            data: bus,
        })
    } catch (error) {
        res.status(500).send({
            success: false,
            message: error.message
        })
    };
})

module.exports = router;

验证步骤

  1. 重启前后端服务,清除浏览器缓存
  2. 打开浏览器开发者工具,查看Network面板中/api/buses/get-all-buses请求的响应状态与数据
  3. 确认页面正常显示班车列表,测试筛选功能是否生效
  4. 检查控制台是否还有React Hooks依赖警告

内容的提问来源于stack exchange,提问作者Вишневский Владислав

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 10:18:07