,都会触发一个完整的重构过程。卸载树时,对应的DOM节点也会被销毁,组件实例会执行componentWillUnmount()方法;当新建一棵树时,会创建对应的DOM节点并插入到DOM中,组件实例会执行componentWillMount()方法,然后componentDidMount()方法比如下面的代码变化:React会销毁注释组件并重新加载新组件而不重用Counter;
2-2比较同类型的元素当比较两个相同类型的React元素时,React会保留DOM节点,只比较和更新变化的属性例如下面的代码更改:通过比较这两个元素,React知道只有DOM元素需要修改
的className属性例如下面的代码改动:当更新style属性时,React只更新change通过比较这两个元素,React知道它只需要修改DOM元素上的颜色样式,而不需要修改fontWeight。
如果是同类型组件element:组件会保持不变,React会更新组件的props,调用componentWillReceiveProps()和componentWillUpdate()方法,接下来调用render()方法,diff算法会递归在以前的结果和新的结果;2-3.子节点的递归默认情况下,在递归DOM节点的子元素时,React会同时遍历两个子元素的列表;当有差异时,产生突变(变化)。如果最后插入一条数据:前两次比较完全相同,所以不会产生变异,最后一次比较会产生变异,可以插入到新的DOM树中,但是如果是在前面插入一条数据,React会为每个子元素生成一个突变,而不是保持
Interstellar和
Inception不变;这种低效的比较方式会带来一定的性能问题,所以要在
- 星际穿越
- 盗梦空间
<之后使用key优化插入一段数据/ul>在前面插入一段数据详见前端高级面试题答案3.记住关键。在diff算法中,可以通过key指定不同渲染下哪些节点是稳定的,并保证key唯一。不使用随机数(随机数会在下次渲染时重新生成一个数字),也不能使用索引,没有针对性能进行优化importReact,{Component}from"react";exportdefaultclassAppextendsComponent{constructor(props){super(props);this.state={电影:[“星际穿越”,“盗梦空间”],};}render(){return(电影列表
{this.state.movi??es.map((item,index)=>{return{item};})}
this.insertMovie()}>添加电影 );}insertMovie(){this.setState({movies:[《大话西游》,...this.state.movi??es],});}}代码分析:默认情况下,在递归DOM节点的子元素时,React会同时遍历两个子元素List;当存在差异时,就会产生突变。如果在电影之后添加数据,前两次比较完全相同,所以不会产生变异;最后的比较会产生一个变异,它会被插入到新的DOM树中。是的;如果在movies前面添加数据,React会为每个子元素生成一个mutation,而不是保持- Interstellar
和- Inception
不变,这种低效的比较方式会带来一定的性能问题。当子元素(这里是li)有key时,React会根据key去匹配原始树上的子元素和最新树上的子元素:在下面的场景中,key为“Interstellar”和“Inception”的元素"只是移位,没有任何修改;将key为“西游记”的元素插入到最前面;