首页 > web前端 > js教程 > 正文

解决 React Hooks 和 MERN 栈中的数据未获取问题

DDD
发布: 2025-09-17 18:34:01
原创
765人浏览过

解决 react hooks 和 mern 栈中的数据未获取问题

本文旨在解决 React Hooks 结合 MERN 开发中,由于 useEffect 依赖项缺失导致数据无法正确获取的问题。通过分析问题代码,我们将深入探讨如何正确使用 useEffect,并结合 useCallback 优化性能,同时提供代码示例,帮助开发者避免类似错误,构建更健壮的 React 应用。

在 React 开发中,useEffect Hook 用于处理副作用操作,如数据获取、订阅事件等。正确使用 useEffect 的依赖项数组至关重要,否则可能导致组件行为异常,例如数据未更新或无限循环。本文将以一个 MERN 栈项目中的巴士信息展示为例,详细讲解如何避免 useEffect 的常见错误,并优化代码性能。

理解 useEffect 的依赖项

useEffect 接收两个参数:一个回调函数和一个可选的依赖项数组。当依赖项数组中的任何一个值发生变化时,回调函数就会被执行。如果依赖项数组为空 [],则回调函数只会在组件挂载时执行一次。如果省略依赖项数组,则回调函数会在每次组件渲染后执行。

在提供的代码中,Home 组件使用 useEffect 获取巴士数据:

useEffect(() => {
    getBuses();
    //setSelectedBus();
  }, [])
登录后复制

控制台提示 "React Hook useEffect has a missing dependency: 'getBuses'"。这意味着 getBuses 函数在组件的生命周期内可能会发生变化,但 useEffect 并未追踪这种变化。因此,getBuses 可能使用了过时的状态或 props,导致数据获取不正确。

解决方案:添加依赖项

要解决这个问题,需要将 getBuses 添加到 useEffect 的依赖项数组中:

BetterYeah AI
BetterYeah AI

基于企业知识库构建、训练AI Agent的智能体应用开发平台,赋能客服、营销、销售场景 -BetterYeah

BetterYeah AI 110
查看详情 BetterYeah AI
useEffect(() => {
    getBuses();
}, [getBuses])
登录后复制

这样,当 getBuses 函数发生变化时,useEffect 就会重新执行,确保获取最新的数据。

优化:使用 useCallback

为了进一步优化代码,可以结合 useCallback Hook 来创建 getBuses 函数。useCallback 会返回一个 memoized 版本的函数,只有当依赖项发生变化时,才会重新创建函数。这可以避免不必要的函数重新创建,提高性能。

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([]);

  const getBuses = useCallback(async () => {
    dispatch(ShowLoading());
    axiosInstance.post("/api/buses/get-all-buses", filters) // Directly use filters
      .then((response) => {
        if (response?.data?.success) {
          setBuses(response.data.data);
        } else {
          message.error(response.data.message);
        }
      })
      .catch((error) => message.error(error.message))
      .finally(() => dispatch(HideLoading()));
  }, [filters, dispatch]); // Add dispatch to dependencies

  useEffect(() => {
    getBuses();
  }, [getBuses])

  const handleOnChange = useCallback(({ target: { name, value } }) => {
    setFilters((prevState) => ({ ...prevState, [name]: value }));
  }, []);

  return (
    <div>
      <div className='my-3 card p-2'>
        <Row gutter={10}>
          <Col lg={6} sm={24}>
            <input type='text'
              placeholder='From'
              value={filters.from}
              name="from"
              onChange={handleOnChange}
            />
          </Col>
          <Col lg={6} sm={24}>
            <input type='text'
              placeholder='To'
              value={filters.to}
              name="to"
              onChange={handleOnChange}
            />
          </Col>
          <Col lg={6} sm={24}>
            <input type='date'
              placeholder='Date'
              value={filters.journeyDate}
              name="journeyDate"
              onChange={handleOnChange}
            />
          </Col>
          <Col lg={6} sm={24}>
            <button className='primary-btn' onClick={() => getBuses()}>
              Filter
            </button>
          </Col>
        </Row>
      </div>
      <div>
        <Row gutter={[15, 15]}>
          {buses.filter((bus) => bus.status === "Yet to start").map((bus) => (
            <Col lg={12} xs={24} sm={24}>
              <Bus bus={bus} />
            </Col>
          ))}
        </Row>
      </div>
    </div>
  )
}

export default Home
登录后复制

代码解释:

  1. useCallback(..., [filters, dispatch]): getBuses 函数现在使用 useCallback 包裹,依赖于 filters 和 dispatch。这意味着只有当 filters 或 dispatch 发生变化时,getBuses 才会重新创建。 并且直接将filters传递给了后端接口,避免了不必要的对象拷贝。
  2. useEffect(..., [getBuses]): useEffect 现在依赖于 getBuses。当 getBuses 函数发生变化时(即 filters 或 dispatch 发生变化),useEffect 重新执行,获取最新的巴士数据。
  3. useCallback(..., []): 使用useCallback创建handleOnChange 函数,并添加了动态的name属性,用于处理input的change事件。

注意事项

  • 确保 useEffect 的依赖项数组包含所有在回调函数中使用的、可能发生变化的值。
  • 使用 useCallback 优化函数,避免不必要的函数重新创建。
  • 仔细检查控制台的警告信息,它们通常能提供关于依赖项问题的线索。

总结

正确使用 useEffect 的依赖项数组是 React 开发中的一项重要技能。通过将所有必要的依赖项添加到数组中,并结合 useCallback 优化函数,可以避免数据获取错误,提高组件性能,并构建更健壮的 React 应用。本文通过一个 MERN 栈项目的实例,详细讲解了如何解决 useEffect 的常见问题,并提供了可复用的代码示例。希望这些信息能帮助开发者更好地理解和应用 React Hooks。

以上就是解决 React Hooks 和 MERN 中的数据未获取问题的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号