React中如何在map函数内累加值并存入useState避免重渲染报错
问题根因
你之所以出现重渲染报错,是因为在组件渲染阶段(JSX中执行map属于渲染逻辑的一部分)调用了useState的更新方法,这会触发组件重渲染,重渲染后又会再次执行map逻辑、再次触发状态更新,最终形成无限渲染死循环。
map方法的核心作用是生成对等数量的元素数组,不建议在map遍历中执行修改状态这类副作用操作。
解决方案
方案1:提前计算总积分(最推荐)
直接在JSX渲染逻辑外,用数组reduce方法提前计算所有用户的积分总和,不需要修改原有map渲染逻辑:
// 在组件return之前计算总和 const totalPoints = users.reduce((sum, user) => sum + user.points, 0); // 渲染部分和原有逻辑一致 return ( <div> <table> <tbody> {users.map((user, index) => { return ( <tr key={index}> <td>{user.fullname}</td> <td>{user.points}</td> </tr> ); })} </tbody> </table> {/* 直接使用提前算好的总和 */} <div>总积分:{totalPoints}</div> </div> );
方案2:用useRef存储遍历累加值(适合需要和渲染判断同步统计的场景)
如果确实需要在遍历过程中做统计(比如要统计满足某渲染条件的用户积分总和),可以用useRef存储累加值,ref的更新不会触发组件重渲染,不会造成死循环:
import { useRef } from 'react'; function YourComponent() { const totalPointsRef = useRef(0); return ( <div> <table> <tbody> {users.map((user, index) => { // 累加操作,更新ref不会触发重渲染 totalPointsRef.current += user.points; return ( <tr key={index}> <td>{user.fullname}</td> <td>{user.points}</td> </tr> ); })} </tbody> </table> <div>总积分:{totalPointsRef.current}</div> </div> ) }
注意:如果你的users数组会更新,需要在每次渲染前重置ref的值:
totalPointsRef.current = 0,避免多次累加历史值。
内容的提问来源于stack exchange,提问作者stronghold051
相关产品推荐
相关产品推荐

