React出现Too many re-renders报错,map循环内调用setState如何解决?
问题根因
- 报错的直接原因是渲染阶段直接调用setState:React组件渲染过程中只要执行
setNewNotifications就会触发组件重渲染,你在users.map的遍历逻辑里每次渲染都重复调用setState,就会形成「渲染→setState→重渲染→再次调用setState」的无限循环,触发React的渲染次数防护机制抛出错误。 - 你的代码还存在其他逻辑问题:
likeNewNotifications和commentNewNotifications可能为null,直接调用concat会抛出类型错误- 组件的return逻辑混乱,把遍历逻辑和JSX返回逻辑混写,原本要渲染的通知DOM实际不会被正确返回
- 直接渲染对象数组
newNotifications会显示[object Object],无法正常展示通知内容
最优解决方案
你需要的通知数据是完全可以基于Redux返回的users数据直接计算得到的衍生数据,完全不需要用useState存储,避免不必要的状态维护和重渲染风险。如果担心数据量大导致重复计算性能损耗,可以用useMemo缓存计算结果。
修正后完整代码
import React, { useMemo } from 'react'; import { useSelector } from 'react-redux'; export default function Notifications() { const users = useSelector(state => state.users) // 用useMemo缓存通知计算结果,只有users变化时才重新计算 const newNotifications = useMemo(() => { const notifications = [] users.forEach(user => { if(!user.posts) return user.posts.forEach(postContent => { // 收集未读点赞通知 if(postContent.like) { const unreadLikes = Object.values(postContent.like).filter(like => like.like_notification === false) notifications.push(...unreadLikes) } // 收集未读评论通知 if(postContent.comments_text) { const unreadComments = Object.values(postContent.comments_text).filter(comment => comment.comment_notification === false) notifications.push(...unreadComments) } }) }) return notifications }, [users]) return ( <div> <p> {/* 遍历渲染通知内容,可根据业务需求调整展示格式 */} {newNotifications.map((notify, idx) => ( <div key={idx}> {notify.userLikeHandle ? `${notify.userLikeHandle} 点赞了你的帖子` : `${notify.commenter_handle} 评论了你的帖子:${notify.commenter_comment}` } </div> ))} </p> </div> ); }
改动说明
- 移除了不必要的
useState状态声明,改为用useMemo计算衍生的通知数据,从根源避免了渲染阶段调用setState导致的死循环 - 修正了通知合并逻辑,避免了null值调用方法的报错
- 理清了组件的返回逻辑,保证通知DOM可以被正确渲染
- 补充了通知列表的渲染逻辑,可正常展示点赞/评论的通知内容
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

