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

预订应用中React useEffect依赖缺失问题求助:避免无限循环

问题

开发预订应用时,点击预订详情按钮可成功获取数据,但React的useEffect钩子出现警告:

React Hook React.useEffect has a missing dependency: 'getDetails'. Either include it or remove the dependency array.

不能移除依赖数组(否则会引发无限循环),尝试添加相关变量后仍有黄色下划线提示,代码如下:

const BookedDetails = () => {

  const { user } = useSelector((state) => state.userAuth)
  const userID = user?.user?._id

  const [details, setDetails] = React.useState([])
  const [loading, setLoading] = React.useState(false)
  const [invoiceLoad, setInvoiceLoad] = React.useState(false)
  const [currentPage, setCurrentPage] = React.useState(1)
  const [postPerPage, setPostPerPage] = React.useState(4)

  const indexOfLastPost = currentPage * postPerPage
  const indexOfFirstPost = indexOfLastPost - postPerPage
  const currenPosts = details.slice(indexOfFirstPost, indexOfLastPost)

 const pages = []

 for(let i = 1; i <= Math.ceil(details.length / postPerPage); i++) {
  pages.push(i)
 }

 const paginate = (x) => {
    setCurrentPage(x)
 }


  const getDetails = async () => {

    const config = {
        headers: {
          "Content-Type": "application/json",
        }
      }

    try {
      setLoading(true)
      const res = await axios.post('/api/bookingDetails/bookDetails', { userID }, config )     
      //console.log(res.data.user)
      setDetails(res.data.user)
      setLoading(false)

    } catch (error) {
      console.log(error.message)
      setLoading(false)
    }
  }

  React.useEffect(() => {
    getDetails()
  },[ ])    //  << dependency is yellow underlined.

}

解决方案

1. 用useCallback缓存getDetails函数

getDetails会在每次组件渲染时重新创建,直接加入依赖数组会触发useEffect重复执行。使用useCallback缓存函数,只有当依赖的userID变化时才重新生成函数,这样就能安全将getDetails加入effect的依赖数组,同时避免无限循环:

import { useCallback } from 'react';

// ... 其他代码保持不变

const getDetails = useCallback(async () => {
  const config = {
    headers: {
      "Content-Type": "application/json",
    }
  }

  try {
    setLoading(true)
    const res = await axios.post('/api/bookingDetails/bookDetails', { userID }, config )     
    setDetails(res.data.user)
    setLoading(false)

  } catch (error) {
    console.log(error.message)
    setLoading(false)
  }
}, [userID]) // 仅当userID变化时,重新创建getDetails

React.useEffect(() => {
  getDetails()
}, [getDetails]) // 加入getDetails作为依赖

2. 将getDetails移入useEffect内部

如果getDetails仅在这个useEffect中调用,直接把函数写进effect内部,这样就不需要额外处理依赖:

React.useEffect(() => {
  const getDetails = async () => {
    const config = {
      headers: {
        "Content-Type": "application/json",
      }
    }

    try {
      setLoading(true)
      const res = await axios.post('/api/bookingDetails/bookDetails', { userID }, config )     
      setDetails(res.data.user)
      setLoading(false)

    } catch (error) {
      console.log(error.message)
      setLoading(false)
    }
  }

  getDetails()
}, [userID]) // 仅需加入userID作为依赖

3. 用ESLint注释忽略警告(不推荐)

如果确认无需依赖更新触发effect,可以添加注释让ESLint忽略警告,但这是临时方案,可能隐藏潜在的依赖问题:

React.useEffect(() => {
  getDetails()
}, []) // eslint-disable-line react-hooks/exhaustive-deps

内容的提问来源于stack exchange,提问作者Peret

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 17:33:14