React子组件首次点击传值父组件为undefined及删除功能异常排查
问题根因
- React 中
useState的状态更新方法是异步批量执行的,调用setPerson_后,当前函数作用域内的person_还是更新前的旧值,要等到下一次组件渲染时才会拿到新值。你在调用setPerson_后立刻把person_传给父组件回调,第一次点击时传的还是初始的空字符串,自然不会有任何联系人被删除;第二次点击时传的是第一次点击后更新的person_值,就出现了删除上一次点击联系人的问题。 - 冗余状态问题:
PeopleList组件完全不需要维护person_这个本地状态,多余的状态声明反而引入了异步更新的bug。
修复代码
直接删除 PeopleList 内多余的状态声明,点击时直接把获取到的联系人名称传给父组件回调即可:
function PeopleList(props) { function handleCLick(e) { // 不需要存本地状态,直接传递获取到的联系人名称 props.handleCLick(e.target.textContent); } return ( <ul onClick={handleCLick}> {props.data.map((val, index) => ( <li key={index}>{val}</li> ))} </ul> ); }
可选优化建议
- 避免用数组索引作为列表项的
key值,后续如果有排序、插入、删除操作会出现渲染异常,无重名的情况下可以直接用联系人名称作为key,更稳妥的方案是给每个联系人新增唯一ID字段作为key - 删除逻辑建议改用函数式更新避免闭包陷阱,修改
removePerson如下:
function removePerson(name_) { // 用函数式更新总能拿到最新的contacts状态,避免闭包导致的状态过时问题 setContacts(prevContacts => prevContacts.filter(value => value !== name_)); }
- 如果存在重名联系人,当前按名称筛选的逻辑会删除所有同名联系人,建议给每个联系人分配唯一ID,删除时按ID筛选。
内容的提问来源于stack exchange,提问作者akerbeltz
相关产品推荐
相关产品推荐

