React组件key变更后仍保留wasEdited状态问题求助
React组件props与key变更时状态未重置的问题
我的React组件在属性(props)和key变更时,仍会保留wasEdited状态。当div元素内容偏离初始值时,该行div的类名会变更,左侧将显示红色边框。
我通过在globalId属性变更时手动重置状态绕过了该问题,但我不理解为何需要这么做——每个Attribute组件都渲染了唯一的key。我怀疑这与相关问题类似,但我并未修改对象。
组件代码
function Attribute ({globalId, name, value}) { const [wasEdited, setWasEdited] = useState(false); const handleInput = (e) => { e.target.innerHTML === value ? setWasEdited(false) : setWasEdited(true); }; // TODO: 这段useEffect是个临时方案,用来在globalId变更时重置wasEdited状态。我不明白 // 为什么这是必须的,因为每个Attribute组件都渲染了唯一的key。我觉得 // 这和某个Stack Overflow上的问题有关,但我并没有修改对象。 // useEffect(() => { // return () => setWasEdited(false); // }, [globalId]) console.log(`${globalId}-${name}`, wasEdited) return ( <div key={`${globalId}-${name}`} className={wasEdited ? 'row was-edited' : 'row'}> <div className='col'>{name}</div> <div className='col' onInput={handleInput} contentEditable>{value}</div> </div> ) }
效果展示

问题原因
你把key加在了组件内部的div元素上,而非Attribute组件本身。React判断组件实例是否复用的核心依据是组件在父级渲染列表中的key,组件内部元素的key完全不影响组件实例的复用逻辑。
当父组件渲染Attribute组件时,如果不给组件本身设置唯一key,哪怕props里的globalId变了,React也会复用之前的组件实例,导致内部的wasEdited状态被保留下来,不会自动重置。
正确解决方案
不需要用useEffect做状态重置的临时处理,只需要在父组件中渲染Attribute时,给组件本身加上唯一key:
// 父组件中渲染Attribute的代码 <Attribute key={`${globalId}-${name}`} globalId={globalId} name={name} value={value} />
同时移除组件内部div上的key(单个元素不需要设置key)。
这样当globalId或name变化时,React会识别到key变更,销毁旧的Attribute组件实例并创建新实例,组件内部的wasEdited状态会自动回到初始的false值。
内容的提问来源于stack exchange,提问作者Vukas Pajic
相关产品推荐
相关产品推荐

