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

React调用setState出现Too many re-renders重渲染错误如何解决

报错根因
  • 两种写法触发死循环的核心原因是 状态更新逻辑直接放在了组件顶层作用域:
    • React组件每次渲染都会执行顶层的所有代码,你调用setRatingFinal会触发组件重新渲染,重新渲染又会再次执行setRatingFinal,形成无限循环,最终触发Too many re-renders报错
    • 遍历过程中直接调用setRatingFinal的写法问题更严重,单次渲染就会触发3021次状态更新,性能和渲染逻辑都会直接崩溃
正确实现方案

有两种常用的实现方式,可根据你的业务场景选择:

  1. 用useEffect封装计算逻辑:仅在依赖项(这里是movies数组)变化时才重新计算并更新状态,适合后续需要修改ratingFinal的场景
  2. 用useMemo缓存计算结果:不需要单独声明状态,直接缓存计算后的数组,适合ratingFinal只用于渲染、不需要后续修改的场景,代码更简洁
可运行代码示例

方案1:useEffect实现(支持后续修改ratingFinal)

import { useState, useEffect } from 'react';

// 示例movies数组,可替换为实际数据源
const movies = Array.from({length: 3021}, () => ({
  "IMDB Rating": +(Math.random() * 10).toFixed(1),
  "IMDB Votes": Math.floor(Math.random() * 10000)
}))

function MovieRatingList() {
  const [ratingFinal, setRatingFinal] = useState([]);

  useEffect(() => {
    // 计算逻辑全部放到useEffect内部,仅在依赖项变化时执行
    const processedList = movies.map(item => {
      return {
        ...item,
        // 计算 votes * rating 的结果
        "RatingTotal": item["IMDB Rating"] * item["IMDB Votes"]
      }
    })
    setRatingFinal(processedList);
  }, [movies]) // 依赖项填movies,仅当movies变化时重新计算

  // 渲染逻辑
  return (
    <div>
      <h3>电影评分统计列表</h3>
      <ul>
        {ratingFinal.map((item, index) => (
          <li key={index}>
            第{index+1}项:评分{item["IMDB Rating"]} * {item["IMDB Votes"]}票 = {item.RatingTotal.toFixed(2)}
          </li>
        ))}
      </ul>
    </div>
  )
}

export default MovieRatingList;

方案2:useMemo实现(仅用于渲染,代码更精简)

import { useMemo } from 'react';

const movies = Array.from({length: 3021}, () => ({
  "IMDB Rating": +(Math.random() * 10).toFixed(1),
  "IMDB Votes": Math.floor(Math.random() * 10000)
}))

function MovieRatingList() {
  // 直接缓存计算结果,依赖变化时自动重新计算
  const ratingFinal = useMemo(() => {
    return movies.map(item => ({
      ...item,
      RatingTotal: item["IMDB Rating"] * item["IMDB Votes"]
    }))
  }, [movies])

  return (
    <div>
      <h3>电影评分统计列表</h3>
      <ul>
        {ratingFinal.map((item, index) => (
          <li key={index}>
            第{index+1}项:评分{item["IMDB Rating"]} * {item["IMDB Votes"]}票 = {item.RatingTotal.toFixed(2)}
          </li>
        ))}
      </ul>
    </div>
  )
}

export default MovieRatingList;

补充说明:如果你的movies数组是通过接口请求获取的,只需要把请求逻辑也放到同一个useEffect中,拿到返回结果后再执行计算逻辑即可,避免重复触发计算。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 09:57:03