讲一下React的生命周期的理解
react生命周期
:从广义上分为三个阶段、挂载(加载)、更新、卸载
React16前的生周期
第一阶段(挂载阶段):
constructor()
:加载的时候调用一次,可以初始化state和绑定方法
getDefaultProps()
:设置默认的props,也可以用defaultProps设置组件默认属性
getInitialState()
:初始化state,可以直接在constructor中定义state
componentWillMount()
:组件加载时调用,整个生命周期只调用一次
render()
:react中最重要的步骤,用于创建虚拟dom,进行diff算法,更新dom树
componentDidMount
:组件渲染之后调用,只调用一次,此时页面已经挂载上真是dom节点
第二阶段(更新)
:
componentWillReceiveProps
: 在组件接收新的props的时候调用
shouldComponentUpdate
:组件收到新props和state的时候调用,如果返回true
则更新dom,如果返回false
则停止更新不调用render
componentWillUpdate
:组件将要更新时调用
render
: 创建虚拟dom,更新dom树
componentDidUpdate
:组件更新完成,此时更新完的dom节点已经挂载到页面上
第三阶段(卸载)
:
componentWillUnmount
:组件将要卸载
react16后的生命周期
第一阶段(挂载)
:
constructor
:加载的时候调用一次,可以初始化state和绑定方法
static getDeriedStateFromProps
:在调用render方法之前调用,并且初始化时会调用后续更新
也会调用,返回一个对象用来更新state,如果返回null则不更新任何内容
render()
:react中最重要的步骤,用于创建虚拟dom,进行diff算法,更新dom树
componentDidMount
:组件渲染之后调用,只调用一次,此时页面已经挂载上真是dom节点
第二阶段(更新阶段)
:
static getDeriedStateFromProps
:在调用render方法之前调用,并且初始化时会调用后续更新
也会调用,返回一个对象用来更新state,如果返回null则不更新任何内容
shouldComponentUpdate
:组件收到新props和state的时候调用,如果返回true
则更新dom,如果返回false
则停止更新不调用render
render()
:react中最重要的步骤,用于创建虚拟dom,进行diff算法,更新dom树
getSnapshotBeforeUpdate
:这个方法触发在render之后,dom挂载到页面上面之前,返回一个值给componentDidUpdate
做为第三个参数
componentDidUpdate
:组件渲染之后调用,只调用一次,此时页面已经挂载上真是dom节点
第三阶段
:
componentWillUnmount()
:组件卸载之前调动,一般用来清除一些timer、取消网络请求等
在React中setState的值和原本的值一样会更新吗? 如果会怎么优化
在react中即使setState
的值和原本的值一样也会更新,如果优化可以通过shouldComponentUpdate
函数进行操作,在这个函数中返回false
就不会重新渲染,并且这个函数有三个参数nextProps、nextState、nextContext
可以供我们比较当前的state、props
下面一个例子用来优化渲染shouldComponentUpdate
里判断
import React,{Component} from 'react'
export default class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {
x:0
}
this.handleBtnClick = this.handleBtnClick.bind(this);
console.log("constructor")
}
shouldComponentUpdate(nextProps, nextState, nextContext) {
if(nextState.x === this.state.x) {
return false;
}
}
handleBtnClick() {
this.setState({
x:this.state.x
})
}
render() {
console.log("render被调用了")
return (
<div>
{this.state.x}
<button onClick={this.handleBtnClick}>click</button>
</div>
)
}
}
React中keys的作用是什么
react中的key可以帮助我们追踪列表中哪些元素被修改、被删除、被添加、被删除
react对比key的来判断是销毁组件还是更新组件
当key相同时,如果组件属性有变化则更新组件
当key不同时,这销毁组件,重新创建
当调用setState的时候发生了什么
调用setState
,React做的以第一件事是将传递给setState
的对象合并到组件的当前状态。
然后和解的过程(reconciliation)
:这个过程的目的是高效更新UI,为React构建一个新的React元素树
然后对比新和旧的两颗树
根据差异进行最小程度渲染
多次调用setState会重复渲染吗
在react中多次setState
传递对象是会被合并成一个,使用参数函数传递不会被合并,并且都只会触发一次渲染不会触发多次
调用setState之后react做了什么(React16之后)
static getDeriedStateFromProps
shouldComponentUpdate
render
getSnapShotBeforeUpdate
componentDidUpdate
为什么setState是一个异步的?
因为当有多个setState的时候,setState需要被合并,并且异步可以提高dom渲染速度
什么是状态提升?
状态提升
:是指两个子组件当需要使用对方的的状态的时候,就需要把子组件的状态写到他们的父组件中,再使用父组件传递到子组件的props
中去。
什么是高阶组件(hoc)
高阶组件
:就是接受一个组件作为参数的函数,并且对组件进行处理最终返回这样的函数称为高阶组件
什么受控组件和不受控组件
受控组件
:在state
中保存组件的属性并且只能用过setState
更新的组件成为受控组件
非受控组件
:不在state
保存组件的属性,并且通过使用ref
来获取数据
受控组件使用场景
:一般需要动态设置初始值的时候使用。
非受控组件使用场景
:用于不需要设置初始化值的时候使用。
为什么说key最好不要用index?
有时候使用index
做为key的时候会影响性能,举个例子现在有一个数组[0,1,2,3]
使用index作为key此时的keys为[0,1,2,3,]那么我们这时候改变数组[3,2,1,0]
此时原本数组的的0
的key为0,那么react就会判断为不同元素然后删除重新渲染
什么是portals?
Portal
:是
react diff原理
- 把树形结构按层分级,同层比较
- 给列表添加key辅助标识
- React