目录
- 虚拟DOM
- ref的使用
虚拟DOM
当组件的state或者props发生改变时,render函数就会重新执行。当父组件的render函数被运行时,它的子组件的render都将被重新运行。
React渲染机制:
1.state 数据
2.JSX模版
3.数据 + 模版结合,生成虚拟DOM.['div', {id: 'abc', ['span', {}, 'hello world']}]
虚拟DOM是一个JS对象
4.用虚拟DOM的结构生成真实的DOM,显示.<div id='abc'><span>hello world</span></div>
5.当state 发生变化后
6.数据 + 模版 生成新的虚拟DOM['div', {id: 'abc', ['span', {}, 'bye-bye']}]
7.比较原始虚拟DOM和新的虚拟DOM的区别,找到区别是span中的内容(Diff算法)
8.直接操作DOM,改变span中的内容
整个过程为:JSX -> React.createElement -> 虚拟DOM (JS 对象 )-> 真实的DOM
引入虚拟DOM的好处:
- 性能提升,从DOM比对变成了JS比对
- 它使得跨端应用得以实现。React Native
虚拟DOM中的Diff算法
1.setstate为什么是异步的?
setState异步.png
性能优化,将多次setState合成一次setState,减少虚拟DOM比对。
2.Diff进行同层比对,逐层去比对,如果发现不同,直接替换,其后面的子
层全部废弃。
逐层比对.png
3.为什么做列表循环的时候要引入key值?
提高虚拟DOM比对的性能,但是key值要保持稳定,不要用index做key值
ref的使用
在react中可以使用ref来获取dom元素。
<input
ref={(input) => {this.input=input}}
value={this.state.inputValue}
onChange={this.handleInputChange}/>
handleInputChange()
通过e.target
获取input的value值,也可修改为const value = this.input.value
但要注意的是:
当ref和setState一起使用的时候,要把操作dom的语法放在setState的第二个参数的函数里面,因为setState是异步函数。这样就可以保证操作dom的方法是在页面渲染后执行的。
handleBtnClick () {
this.setState((prevState) => ({
list: [...prevState.list, prevState.inputValue],
inputValue: ''
}), () => {
console.log(this.ul.querySelectorAll('div').length)
})
}
如果将console.log(this.ul.querySelectorAll('div').length)
放在setState后面,就会出现下面的情况,获取到的div总是比实际少一个。
(完)
网友评论