React组件执行函数后变量变为undefined的原因排查
问题分析与解决方案
核心原因推测
后端返回数据丢失
poolId
首次删除后,后端返回的res.pool对象可能未包含id(即poolId)字段。祖父组件的updateData函数直接用setPool(data.pool)替换整个池状态,导致新状态丢失poolId,后续子组件接收的props.poolId变为undefined。使用索引作为
key引发的组件复用问题
遍历droplets时用index作为元素key,删除元素后剩余项的索引会发生偏移,React可能错误复用旧组件,导致事件绑定的dropletId或props出现 stale(过期)值。未缓存
removeDroplet函数导致的过期闭包removeDroplet函数每次组件渲染都会重新创建,但如果组件或父组件使用了memo优化,可能导致事件绑定的仍是旧版本函数,捕获的props.poolId为过期值。
具体修复步骤
1. 确保后端返回完整的池对象
检查DELETE接口的返回值,确认res.pool包含id字段。如果后端无法修改,可在祖父组件的updateData函数中手动保留原poolId:
const updateData = (data) => { if (data.pool) { // 保留原poolId,避免丢失 setPool({ ...data.pool, id: pool.id }); } else { setPool({ ...pool, ...data.createdPool }); } };
2. 替换索引为唯一key
将遍历的key从index改为droplet.id,确保React能正确识别每个元素:
{props.droplets.map((droplet) => { return ( <table key={droplet.id} // 用droplet唯一ID替代index className="droplet-results" > {/* ... 原有代码 ... */} </table> ); })}
3. 缓存removeDroplet函数
用useCallback缓存函数,确保它始终捕获最新的props:
import { useCallback } from 'react'; const removeDroplet = useCallback((dropletId) => { fetch(`http://localhost:5000/api/pools/${props.poolId}/${dropletId}`, { method: "DELETE", headers: { "Content-Type": "application/json", }, }) .then((res) => res.json()) .then((res) => props.updatePoolData(res)) .catch((error) => console.error(error)); }, [props.poolId, props.updatePoolData]); // 依赖项包含用到的props
内容的提问来源于stack exchange,提问作者Finnjon
相关产品推荐
相关产品推荐

