react中的reconciliation
在react高级指南中说到了一个reconciliation(协调),这部分的内容主要说明了在react中,怎样去渲染,怎样去协调你的代码。在这里说到了一个DIFF算法,其算法复杂度为O(n)。那么这个算法有什么用呢,它主要用于去比较你的DOM结构,然后进行元素的渲染过程。对于虚拟DOM的描述,主要是以下的过程
虚拟DOM:
react中的虚拟dom
在react中,执行的步骤
1.首先生成state数据
2.然后生成JSX的模板
3. state + JSX模板,生成虚拟DOM(虚拟DOM就是一个JS对象,用来描述真实的DOM),
例如如果真实的DOM是
<div id = 'abc'><span>hello</span></div>
则在虚拟DOM中其采用的形式就是下面这种,
React.createElement('div','{}','React.createElement('spn','{}','hello')')
4.生成真实的DOM
5.state数据改变
6.state + JSX模板,生成一个新的虚拟DOM
7.原始的虚拟DOM和新生成的虚拟DOM进行比较,找出改变的数据
(虚拟DOM直接的比较算法时DIFF算法,DIFF算法的比较原理是同级比较,如果发现
原始同级不同,则直接重新渲染所有的结点,然后再进行下一个节点的比较,这样做的好处
是算法比较简单。如果有多处的setState(异步函数)连续发生改变,则在虚拟DOM中,其进行的方式就是
同时发生,这样会提高性能)
8.只改变原来DOM中改变的数据中的元素。
只要明白了这个过程,就在很大程度上去认识到了react中是如何协调你react树的,DIFF算法会比较你DOM节点,以及属性,一旦这些内容不同时,就会将原来的DOM树给删除,换成新的节点,但是在react并没有将这个DOM树给构建起来。因此叫其为虚拟DOM,这样的好处就是大大的提高你整个程序的性能与运行速率。
ref and DOM
对于其提供了一种方式在render方法中去接受DOM节点和组件元素
在典型的React数据流传递过程中,props是唯一的一种方式去将父组件中的数据传递到子组件当中,为看改变子节点,你需要将子节点再一次的渲染作为一个新的props,然而在某些情况下你需要去强制的更改典型的数据流的模式。那么ref是一种方式去改变子节点在组件元素和DOM节点中都可以去使用。
ref的应用的一些位置:
1. 管理聚焦 ,文本框的选择,媒体播放器的播放 2. 触发命名动画 3. 与第三方库集成的时候
切记不要去过渡的使用ref,因为在有的时候拥有此状态的层级在比较高的位置
ref相关的语法
怎样去创建ref,ref的创建要使用React.createRef(),然后经由React元素中的属性进行绑定,下面就体现了这样一个过程
接收ref属性,其具体是什么类型,取决你节点的类型,对于节点的应用应该使用的语法是const node = this.Myref.current
1.如果你接受的节点是html中的DOM节点,那么其就是一个DOM节点; 2.如果你接收的结点时react中的元素,那么其就是一个元素节点 3.可能不会在函数组件上去使用ref因为对此并没有什么实际例子
上面的这个例子是ref运用在DOM节点中的类型
这上面的这个例子是应用在react中元素节点上的,需要注意的是这种方式是应用在类组件上的
当你这样去使用ref时,程序是不会运行的,因此你可以采用下面的这种形式去进行表达
将DOM直接暴露给父组件
在有的时候你想在父组件中去访问子节点的DOM,这种情况打破了原有的react结构,通常在很多情况下是不被采用的,但是在有的时候,对于触发焦点或测量子DOM节点的大小或位置很有用。如果您使用React 16.3或更高版本,我们建议在这些情况下使用ref转发。Ref转发允许组件选择将任何子组件的Ref公开为它们自己的。
回调ref
react中也支持另外一种方式去使用ref,那就是回调ref,这样就给出了一种好的方式,对于何时去设置与去除。那门这种方式是怎样的呢,其实质是通过函数接收React组件实例或HTML DOM元素作为其参数,该参数可以存储在其他地方并访问。下面就展示了一个这样的例子
React将在组件挂载时使用DOM元素调用ref回调,在卸载时使用null调用它。保证Refs在componentDidMount或componentDidUpdate触发之前是最新的
也可以在组件之间的传递去实现这种回调调用过程
对于string ref,在官方文档上说,其具有很多问题因此在这里不做深究。
以上内容就是关于ref和react中的协调相关的一些问题。