React高频面试题梳理,看看面试怎么答?

**1.React生命周期有哪些,16版本生命周期发生了哪些变化?
**在这里插入图片描述
初始化阶段
constructor 构造函数
getDefaultProps props默认值
getInitialState state默认值

挂载阶段
componentWillMount 组件初始化渲染前调用
render 组件渲染
componentDidMount组件挂载到 DOM后调用
更新阶段
componentWillReceiveProps 组件将要接收新 props前调用
shouldComponentUpdate 组件是否需要更新
componentWillUpdate 组件更新前调用
render 组件渲染
componentDidUpdate 组件更新后调用
卸载阶段
componentWillUnmount 组件卸载前调用

16生命周期
初始化阶段
constructor 构造函数
getDefaultProps props默认值
getInitialState state默认值
挂载阶段
staticgetDerivedStateFromProps(props,state)
render
componentDidMount
getDerivedStateFromProps:组件每次被 rerender的时候,包括在组件构建之后(虚拟 dom之后,实际 dom挂载之前),每次获取新的 props或 state之后;每次接收新的props之后都会返回一个对象作为新的 state,返回null则说明不需要更新 state;配合 componentDidUpdate,可以覆盖 componentWillReceiveProps的所有用法
更新阶段

staticgetDerivedStateFromProps(props,state)
shouldComponentUpdate
render
getSnapshotBeforeUpdate(prevProps,prevState)
componentDidUpdate

getSnapshotBeforeUpdate:触发时间: update发生的时候,在 render之后,在组件 dom渲染之前;返回一个值,作为 componentDidUpdate的第三个参数;配合 componentDidUpdate, 可以覆盖 componentWillUpdate的所有用法
卸载阶段

componentWillUnmount

错误处理

componentDidCatch
React16新的生命周期弃用了 componentWillMount、componentWillReceivePorps,componentWillUpdate新增了 getDerivedStateFromProps、getSnapshotBeforeUpdate来代替弃用的三个钩子函数。
React16并没有删除这三个钩子函数,但是不能和新增的钩子函数混用, React17将会删除这三个钩子函数,新增了对错误的处理( componentDidCatch)

setState是同步的还是异步的?

生命周期和合成事件中
在 React的生命周期和合成事件中, React仍然处于他的更新机制中,这时无论调用多少次 setState,都会不会立即执行更新,而是将要更新的·存入 _pendingStateQueue,将要更新的组件存入 dirtyComponent。

当上一次更新机制执行完毕,以生命周期为例,所有组件,即最顶层组件 didmount后会将批处理标志设置为 false。这时将取出 dirtyComponent中的组件以及 _pendingStateQueue中的 state进行更新。这样就可以确保组件不会被重新渲染多次。

componentDidMount(){
	this.setState({
	index:this.state.index +1
)}
console.log('state',this.state.index)

所以,如上面的代码,当我们在执行 setState后立即去获取 state,这时是获取不到更新后的 state的,因为处于 React的批处理机制中, state被暂存起来,待批处理机制完成之后,统一进行更新。

所以。setState本身并不是异步的,而是 React的批处理机制给人一种异步的假象。

异步代码和原生事件中

componentDidMount(){
setTimeout(()=>{
	console.log('调用setState')
	this.setState({
	index:this.state.index +1
)}
console.log('state',this.state.index),0);
}

如上面的代码,当我们在异步代码中调用 setState时,根据 JavaScript的异步机制,会将异步代码先暂存,等所有同步代码执行完毕后在执行,这时 React的批处理机制已经走完,处理标志设被设置为 false,这时再调用 setState即可立即执行更新,拿到更新后的结果。

在原生事件中调用 setState并不会出发 React的批处理机制,所以立即能拿到最新结果。

最佳实践
setState的第二个参数接收一个函数,该函数会在 React的批处理机制完成之后调用,所以你想在调用 setState后立即获取更新后的值,请在该回调函数中获取。

this.setState({index:this.state.index+1},()=>{
	console.log(this.state.index);
	})

为什么有时连续多次setState只有一次生效?
例如下面的代码,两次打印出的结果是相同的:

componentDidMount(){
	this.setState({ index:this.state.index +},()=>{
	console.log(this.state.index);
	})
	this.setState({ index:this.state.index +},()=>{
	console.log(this.state.index);
	})
}

原因就是 React会批处理机制中存储的多个 setState进行合并,来看下 React源码中的 _assign函数,类似于 Object的 assign:

 _assign(nextState,typeof partial ==='function'partial.call(inst,nextState, props,context):partial);

如果传入的是对象,很明显会被合并成一次,所以上面的代码两次打印的结果是相同的:

Object.assign(
nextState,
{index : state.index +1},
{index : state.index +1},
)

注意, assign函数中对函数做了特殊处理,处理第一个参数传入的是函数,函数的参数 preState是前一次合并后的结果,所以计算结果是准确的:


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值