React 基础
状态组件和无状态组件
状态组件和无状态组件的差异是一个拥有state,另外一个没有。
对于无状态组件,因为他没有自己的state也就不能够检测state的变化。只是作为上层组件的一部分,在上层组件状态更改的时候重新渲染。
同时,对于无状态组件的写法可以更加的简洁,就只是一个纯函数而已,接收props参数。
虚拟DOM
React自己维持一个虚拟的dom,每次在更新视图的时候(setState),react就会检测屏幕上的DOM与自己维护的虚拟DOM之间的差异。
渲染列表问题
我们在使用数组渲染一个列表的时候大概会遇到这么一个报错,Each child in a list should have a unique "key" prop.
。
报这个错误的原因就是因为虚拟DOM,因为如果在重新渲染列表比较差异的时候,虚拟DOM不知道,各个子项之间如何区分,所以就需要我们手动提供一个唯一的key
。
视图的异步更新问题
总所周知,JavaScript是单线程的。那么在假如一个组件的状态正在更新,他正在屏幕上面渲染,那么此时有一个更加重要的任务,react应该如何处理呢?
假如是等待原来那个视图渲染完成才开始执行那个更重要的人物的话,在用户看来界面就是变卡了,就是不好的体验。
所以react的处理方式就是在更新状态的时候每个一段时间就会出来看看,寻找有没有什么更加重要的事情需要处理,如果有的话,就先停下手中的工作,去处理那个更加重要的工作。
props和state
一个组件的state是私有的,可以改变的。但是props来自上层的传递。react遵守的规则是像一个纯函数一样绝不更改上层传递而来的props。
一般来讲上层组件集中管理(管理而不是存储)下层组件的state。
当一个组件发现它的state被更改以后,就会将自己重新进行渲染。要注意的是一个组件的state是不能够直接更改的,而应该通过setState
方法更新。state只能在构造函数中进行初始化。
当执行setState
是ReactDOM会检测提供的状态和屏幕显示元素state的差异,并且只更新这个差异,而不是更新屏幕显示元素的本身。简单来说就是react并不主动检测更新,而是通过setState告知其需要更新,同时React通过进行虚拟DOM与浏览器DOM的比较,更新最小的差异。
对于自定义的组件,当调用时,会将其属性作为props
传递。
props就像是电流一样,在react组件中进行传递,而一个一个的react元素就像是电器一样,根据电流改变他们的('states')状态。
生命周期
每一个react组件都有自己的生命周期,从他们被创建出来,显示在屏幕上,一直到他们从屏幕上消失。可以将他们的声明周期划分为,挂载,更新和卸载三个阶段。
声明周期钩子
能够在组件声明周期的特定时间节点执行某些操作的函数就叫做声明周期钩子。
上面的图介绍了在不同阶段开发人员最常用的几个生命周期钩子。
在组件被实例化并插入到ReactDOM时,在更新真实DOM之前也就是MOUNT阶段(constructor->render->componentDidMount)。
之后组件的stat/props改变的话,也就到达UPDATE阶段,组件再次执行自己的渲染方法(render),并且在React比较真实DOM和虚拟DOM之间的差异,更新差异之后。执行componentDidUpdate方法。
如果在上层组件的UPDATE阶段,发现某个子组件在虚拟DOM中已经不存在,那么就将触发这个子组件的componentWillUnmount方法。
JSX
React元素
React元素实际上就是一个js对象,最后通过React的render方法才将其转换成为DOM元素显示在浏览器上。
jsx的语法实际上也就是用像是html标签的方式创建这个React元素,而不用使用React.createElement
创建,最大的好处就是语法简单,结构清晰。
JSX中的花括号
实际上也就是通过花括号表示这个一个js表达式,这个js表达式可以返回任何值。
React.Fragment
由于jsx的语法本质上还是js,所以每次每次返回的时候只能返回一个React元素,所以有时候需要返回多个元素的时候我们就会使用div将其包裹起来。
如果不想要使用这个无意义的div标签的话,那么我们可以将要返回的多个React元素放在React.Fragment组件中。