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

React自定义usePoll Hook触发setState时hook渲染数量少于预期报错求助

问题根因

你触发Rendered fewer hooks than expected报错的核心原因是违反了React Hook的调用规则:所有Hook必须在组件的最顶层作用域调用,不能包裹在条件判断、循环、嵌套函数内部。
你当前的代码里把usePoll放在了if ([...Statues].includes(report.status))的条件块内,当这个条件第一次为true时会调用usePoll,后续渲染如果条件变为false就不会调用这个Hook,导致两次渲染调用的Hook数量不一致,就触发了这个报错。

修复方案

第一步:改造usePoll自定义Hook,增加启停控制参数

给usePoll加一个enabled参数,用来控制轮询是否真正执行,不需要在外层通过条件判断是否调用Hook:

export function usePoll(callback: IntervalFunction, delay: number, enabled: boolean = true) {
  const savedCallback = useRef<IntervalFunction | null>()

  useEffect(() => {
    savedCallback.current = callback
  }, [callback])

  useEffect(() => {
    // 未启用时直接返回,不创建定时器
    if (!enabled) return
    function tick() {
      if (savedCallback.current !== null) {
        savedCallback.current()
      }
    }
    const id = setInterval(tick, delay)
    return () => clearInterval(id)
  }, [delay, enabled]) // 把enabled加入依赖项
}

第二步:调整组件内的调用逻辑,把Hook移到顶层

把原来的条件判断改为传给usePoll的enabled参数,所有Hook都放在组件最顶层调用:

const BankLink: React.FC = ({ report: _report }) =>  {
  const [report, setReport] = React.useState(_report)
  // 先计算轮询启用条件
  const pollEnabled = [...Statues].includes(report.status)

  // 顶层调用usePoll,不使用条件包裹
  usePoll(async () => {
    const initialStatus = _report.status
    const { result } = await apiPost(`/links/search`)
    const currentReport = result.results.filter((item: { id: string; }) => item.id === _report.id)
    if (currentReport[0]?.status !== initialStatus) {
      // 直接调用setReport更新状态即可,如果你封装了handleSetReportState逻辑也可以正常调用
      setReport(currentReport[0])
      console.log('status changed')
    } else {
      console.log('status unchanged')
    }
  }, 5000, pollEnabled)
  // ... 剩余组件逻辑
}
额外注意点
  • 你原代码里apiPost调用多了一个多余的右大括号,记得删掉避免语法报错
  • 取currentReport[0]的时候最好加可选链?.判断,避免接口返回空数组时报错
  • 如果_report属性可能会被外层组件更新,建议加useEffect同步props到state:
useEffect(() => {
  setReport(_report)
}, [_report])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 14:27:02