React报错求助:渲染ItemLists时更新MoneyIn组件的setState问题
错误定位与修复方案
核心问题:子组件渲染时直接触发了父组件的状态更新
看子组件ItemLists里的这行代码:
const handleDelete = props.handleDelete();
这里你直接调用了props.handleDelete(),而非保留函数引用。如果handleDelete内部包含父组件MoneyIn的setNewItems(状态更新操作),那在ItemLists渲染过程中就会触发父组件的状态变更,违反了React的渲染规则——不能在一个组件渲染期间更新另一个组件的状态,这就是报错的直接原因,甚至会因为反复触发渲染更新形成循环,导致浏览器冻结。
修复步骤
- 修正子组件的函数引用方式
把调用函数改为直接引用,只在点击时执行:
// 子组件ItemLists中 const handleDelete = props.handleDelete; // 去掉后面的()
- 补全父组件的
handleDelete实现
确保父组件的删除函数正确处理状态更新,推荐用函数式更新避免闭包问题:
// 父组件MoneyIn中 const handleDelete = (itemToDelete) => { setNewItems(prevItems => prevItems.filter(item => item !== itemToDelete)); };
- 优化父组件的总价计算逻辑
用useMemo缓存总价计算结果,避免无效重复计算:
// 父组件MoneyIn中 import { useMemo } from 'react'; const totalSellingPrice = useMemo(() => { return newItems.reduce((total, item) => total + parseFloat(item.sellingPriceOfTotal), 0); }, [newItems]);
同时把displayAddedItemList的逻辑直接整合到JSX中,避免函数调用式的渲染写法:
// 父组件MoneyIn的返回JSX中 return ( <div> {/* 其他业务代码 */} {!visible && ( <div> <div>Items</div> <ItemLists newItems={newItems} handleDelete={handleDelete}/> <div className='totalItemsAdded'> <p>Total</p> <p>${totalSellingPrice}</p> </div> </div> )} </div> );
冻结原因说明
子组件渲染触发父组件状态更新,父组件更新后重新渲染子组件,子组件再次触发状态更新,形成无限渲染循环,最终耗尽浏览器资源导致冻结。
内容的提问来源于stack exchange,提问作者Aham_Uzoma
相关产品推荐
相关产品推荐

