TL; DR:我是否可以信任协调算法不重新实例化我的有状态组件只是因为虚拟DOM中的更改过于复杂而无法跟踪它?
我相信,React.Component实例是由React运行时创建和销毁的,以匹配Virtual DOM的形状。作为程序员,我声明性地描述了虚拟DOM,实例的生命周期由React本身控制。据我所知,当Virtual DOM改变其形状时,特殊的协调算法会尽可能多地重用旧实例。另外,我理解如果唯一的区别在于道具,那么旧的实例只需通过生命周期方法更新道具并通知它。
我还希望,对于简单地将道具映射到虚拟DOM的功能组件,谈论生命周期没有意义,因为如果这是相同或不同的实例并不重要。特别是,人们不必相信协调算法非常智能,因为无论是具有更新道具的新实例还是新实例,组件的外观和行为都是相同的。
但在有状态组件的情况下,我是否可以信任协调算法?
说,我有一个组件可以在其状态中直接存储一些数据并直接在其实例上存储。此外,我们假设该组件的构造函数初始化它们:
constructor(props) {
super(props);
this.state = {
value: ''
};
this.length = 0;
}
此外,假设由于用户操作而导致状态及时发展
onChange = (e) => {
this.setState({value: e.target.value}
this.length = e.target.value.length;
}
我可以,或者我不能,假设这个实例不会在React框架的一时兴起被杀死和重建吗?上面的组件不是“功能性的”,因为它具有内部状态,作为开发人员,我认为即使在协调期间组件树的较高部分发生了复杂的事情,我也会以某种方式“保留”。
从文档和Web中的许多示例中,我理解,社区假定实例的状态和私有属性不会重置,除非父级显式更改key
属性,或者获取摆脱孩子,并在以后实例化一个新的。但这些假设是否在文档中明确说明了?
而另一方面的问题是:改变一个孩子的key
保证要创建一个新实例,或者可以做出反应决定重用一个具有不同密钥的旧实例(从而重新使用其状态) )?换句话说:the key trick保证可以工作还是只是一个黑客?
修改 问题情况的一个例子:https://codesandbox.io/s/9rqrPJnLD。这里我们有一个有状态的组件:
class Stateful extends React.Component{
state = { now: new Date()};
render(){
return <div>{this.state.now.toString()}</div>
}
}
生活在一个充满敌意的环境中,父母常常会改变对布局的看法,而且孩子有时会嵌套在div中,有时不会嵌套:
class App extends React.Component{
state = { div: true}
componentDidMount(){
setInterval(()=>{
this.setState(state => {
return {div: !state.div}
});
},2000)
}
render(){
return React.createElement(this.state.div ? 'div' : 'span',null,React.createElement(Stateful))
}
}
似乎每次父级更改布局时都会重新实例化子级,并且在发生状态时不会保留状态。这部分回答了我自己的问题。未解决的部分是:和解算法难以解决的其他案例是什么。