如何从React父组件获取最新state同步Tree子节点选中状态
问题根因
你当前的useEffect依赖数组为空,只会在Node组件首次挂载时执行1次,后续父组件传入的list更新时不会触发重执行,因此始终读取的是首次挂载时的旧list值。
解决方案1:补全useEffect依赖
将props.list和label加入useEffect的依赖数组,只要这两个值发生变化就会重新执行逻辑,读取最新的list判断选中状态:
useEffect(() => { const inList = props.list.find(item => item.name === label) !== undefined setChecked(inList) }, [props.list, label])
优化建议:用Array.some替代find判断,匹配到目标项后会直接返回布尔值,无需遍历完整数组,性能更好:
useEffect(() => { setChecked(props.list.some(item => item.name === label)) }, [props.list, label])
解决方案2:直接从props派生状态(更推荐)
选中状态的唯一数据源是父组件的list,完全不需要在Node组件内部维护单独的checked本地状态,直接从props计算即可,从根源避免多数据源不同步的问题,也省掉了useEffect的开销:
export const Node = (props) => { // 直接从父组件传入的list计算选中状态 const checked = props.list.some(item => item.name === someLabel) const handleCheckbox = () => { if(!checked){ props.updateList(someLabel) } else{ props.removeFromList(someLabel) } } return( <TreeItem icon = {<Checkbox checked={checked} onChange={handleCheckbox}/>} > {expanded && !fetching ? childNodes : <TreeItem label="reached end" />} </TreeItem> ) }
这个方案天然适配TreeView折叠销毁子组件、展开重新挂载的场景,每次组件渲染都会拿最新的list计算状态,不会出现状态丢失的问题。
内容的提问来源于stack exchange,提问作者qBoss
相关产品推荐
相关产品推荐

