React高级
PropTypes与DefaultProps
- 每个组件都有自己的props参数,这个参数是从父组件接收的一些属性,如何对参数的类型做校验,如何定义参数的默认值,这就需要用到PropTypes和DefaultProps
React中的ref
- React中利用ref直接获取元素对应的DOM
- 但是不推荐使用ref,React建议使用数据驱动的方式来编写代码,尽量不要直接操作DOM,除非在一些及其复杂的业务中,如操作动画
- 使用ref可能会遇到各种各样的问题,如ref与setState合用时,可能会出现DOM更新不及时,导致获取的DOM不准确,原因时setState是异步的,如果希望页面更新后,在去获取DOM,一定要记得把获取DOM的语法,放在setState的第二个参数的函数中,它是一个回调函数
Props,State与render函数
- react是一个由数据驱动的框架,当数据发生变化,页面就会自动跟着变化,它背后的原理是什么呢?
- 当组件的state或者props发生改变的时候,render函数就会重新执行
- 当父组件的render函数被运行时,它的子组件的render函数都将被重新运行
- 之所以子组件的render函数会被重新执行,可以从两方面理解:1)它的props本身发生了改变,2)它是父组件的一个子组件,父组件的render函数被重新执行时,子组件的render函数也会被重新执行一次
React中的虚拟DOM
- 当组件的props或者state数据发生变化的时候,组件的render函数就会重新被执行,组件就会被重新渲染,react中实现这种重新渲染,他的性能是非常高的,因为它引入了一个虚拟DOM的概念
- 如何实现虚拟DOM?
- react中引入虚拟DOM,为什么提升性能?因为它减少了对真实DOM的创建以及真实DOM的对比,取而代之,创建的都是JS对象,对比的也都是JS对象,通过这种方式,react底层实现了极大的性能飞跃
- 虚拟DOM本质上就是一个JS对象,本质上它能提高性能,是因为js中去比较js对象不怎么耗费性能,去比较真实的DOM会很耗费性能
深入了解虚拟DOM
- react底层操作: JSX模版 -> createElement ->(虚拟DOM)JS对象 -> 真实的DOM
- JSX语法的存在,是为了方便代码书写,更方便,更简洁
- 虚拟DOM带来的好处:
- 性能提升(DOM的比对,变为js对象的比对)
- 使得跨端应用得以实现(在网页中,可以使用虚拟DOM生成真实的DOM,进而在浏览器中渲染出真实的页面,在RN原生应用中,可以使用虚拟DOM生成原生的组件,进而展示原生的页面,所以React既可以开发网页应用,又可以开发原生应用)
虚拟DOM中的diff算法
- 虚拟DOM(JS对象)比对的方式,就叫做Diff算法,(difference),实际上,React的Diff算法,大大的提升了两个虚拟DOM之间的比对性能
- 什么时候数据会发生变化,其实都是当调用setState时,数据才会发生变化,然后虚拟DOM才重新比对
- setState其实是异步的,它在react底层的一个性能优化实现是,将多次setState结合为一次setState,减少虚拟DOM比对的次数
- Diff算法比对两个虚拟DOM差异时,它会逐层比对,如果一层不满足匹配要求,那下面的就不会再去比对了,直接废弃掉,用新的替换掉旧的
- Diff算法中,有个很重要的概念,叫做同层比对,即只比对同层虚拟DOM,发现差异后,不会再继续比对,整个对原始DOM进行全部替换,好处:比对算法简单,比对速度很快,虽然可能造成DOM重新渲染的一些浪费,但大大减少了DOM比对算法上的性能损耗
- 为什么React中做列表循环时,要引入key值?在做虚拟DOM的比对循环时,当增加key值后,虚拟DOM的比对,会根据key值做关联,有关联的元素就可以直接复用,只需要把没有做关联的元素增加到DOM树上即可,这样就提高了虚拟DOM比对的性能,但是要提高性能有一个前提,就是比对前后的key值不变,key值要保持稳定,所以不能用index做key值,因为增删dom后,index就移位了,元素对应的key值就不稳定了,这就失去了key值的意义,无法做关联复用了