React技术疑问:为何setState会导致无状态组件内的组件卸载?
为什么在无状态组件内部调用setState会导致组件被卸载?
咱们先拆解你遇到的问题核心,根源其实不在setState本身,而是你定义无状态组件的位置不对!
问题出在哪?
你在render()方法内部定义了Box这个无状态组件:
render() { // ...其他代码 var Box = ()=>{ return <NumberBox step = {1} value={value} onChangeValue={onChangeValue}/>; }; // ...返回JSX }
React判断两个组件是不是“同一个类型”,是看组件的函数/类引用是否一致的。每次调用setState({})时,组件会触发重新渲染,也就是重新执行一遍render()方法——这时候Box会被重新定义一次,相当于每次render出来的Box都是一个全新的函数,和上一次渲染的Box不是同一个“组件类型”了。
React的diff算法逻辑
当React对比前后两次的虚拟DOM树时,如果发现某个位置的组件类型发生了变化(这里就是旧的Box和新的Box引用不同),它会直接卸载旧的组件实例,然后重新挂载一个新的组件实例。这就是你看到组件被卸载的原因。
而你代码里直接渲染的<NumberBox/>没有这个问题,因为它是在render()外部定义的,每次渲染时引用都是同一个,React会认为是同一个组件,只会做更新操作而不会卸载重建。
怎么解决?
把Box的定义移到render()方法外面,让它的引用保持固定:
// 把Box组件移到render外部,确保每次渲染时引用不变 const Box = ({ value, onChangeValue }) => { return <NumberBox step={1} value={value} onChangeValue={onChangeValue} />; }; class Application extends React.Component { // ...你的其他代码 render() { const onChangeValue = (val) => { // 另外提一句:全局变量value不是React的正确用法,建议把value放到组件state里哦 value = val; this.setState({}); }; return ( <div> <Box value={value} onChangeValue={onChangeValue} /> <NumberBox step={1} value={value} onChangeValue={onChangeValue} /> </div> ); } }
这样不管组件怎么触发重新渲染,Box的引用都是同一个,React就会把它当成同一个组件处理,不会再出现卸载重建的问题了。
内容的提问来源于stack exchange,提问作者heroboy
相关产品推荐
相关产品推荐

