React中数组已存入元素但删除函数内检测为空的问题咨询
问题根因
- 闭包捕获问题:你声明的
useEffect依赖为空数组,仅会在组件首次挂载时执行1次。此时绑定的deleteDailyStandItem函数捕获到的dailyStandItemsDisplayed是初始值(空数组),后续即使该state更新,闭包内的变量也不会同步刷新,所以打印结果永远为空。 - 状态存储不规范:你直接将JSX元素存入
dailyStandItemsDisplayed状态,不符合React最佳实践。状态应当仅存储原始业务数据,渲染逻辑需放在组件的return部分,否则很容易出现状态不同步、事件回调异常的问题。 - 冗余的状态更新逻辑:你在循环中多次调用
setDailyStandItemsDisplayed,不仅性能差,也会提升状态不同步的概率。
修复方案
按照如下规则调整代码即可解决问题:
- 调整state的存储内容,仅保存文章的原始数据,不存储JSX元素
- 将文章渲染逻辑转移到组件return部分,遍历原始数据动态生成DOM
- 简化异步回调中的状态更新逻辑,单次赋值完整数据数组
修复后代码示例:
// 初始化state,仅存储文章原始数据,初始值为空数组 const [dailyStandItemsDisplayed, setDailyStandItemsDisplayed] = useState([]) const [dailyStand, setDailyStand] = useState(null) const deleteDailyStandItem = (id) => { console.log(dailyStandItemsDisplayed) // 此时可正常拿到最新的文章数组 // 此处添加删除数据库的逻辑,请求成功后更新本地状态 setDailyStandItemsDisplayed(prev => prev.filter(item => item.id !== id)) } useEffect(() => { getDailyStand() .then(dailyStandDB => { if(dailyStandDB){ setDailyStand(dailyStandDB) return getDailyStandDetails() } }) .then(dailyStandItemsDB => { if(dailyStandItemsDB){ // 单次赋值完整的文章数据数组,无需循环更新 setDailyStandItemsDisplayed(dailyStandItemsDB) } }) }, []) // 渲染逻辑写在组件return中 return ( <div className="daily-stand-list"> {dailyStandItemsDisplayed.map(item => ( <article key={item.id}> <section> <img src={config.dailystand_detail_pict_url + item.pict_url} alt={`illustration${item.id}`} /> </section> <p>Description : {item.description}</p> <Button onClick={() => deleteDailyStandItem(item.id)}> <DeleteIcon /> </Button> </article> ))} </div> )
内容的提问来源于stack exchange,提问作者Tholhen
相关产品推荐
相关产品推荐

