React几道高频面试题 内附解答

241 阅读3分钟

react生命周期

react 生命周期氛围两个版本。如下

react < 16

first render

  • getDefaultProps
  • getInitalState (constructor > this.state)
  • componentWillMount
  • render
  • componentDidMount

Props change

  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

State change

  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

component Unmount

  • componentWillUnmount

react > 16

Not recommended

  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillMount

first render

  • constructor
  • static getDerivedStateFromProps
  • render
  • componentDidMount

update

  • static getDerivedStateFromProps
  • shouldComponentUpdate
  • render
  • getSnapshotBeforeUpdate
  • componentDidUpdate

Unmount

  • componentWillUnmont

新增生命周期介绍

static getDerivedStateFromProps(props, state)

getDerivedStateFromProps会在调用render之前调用,并且在初始挂载和后续更新时会调用。返回object更新state,返回null不更新。

getSnapshotBeforeUpdate(prevProps, prevState)

getSnapshotBeforeUpdate() 在最近一次渲染输出(提交到 DOM 节点)之前调用。它使得组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。此生命周期的任何返回值将作为参数传递给 componentDidUpdate()。

React的请求应该放在哪个生命周期中?

目前官方推荐的异步请求是放在 componentDidMount 中进行。

有很多人会认为react的异步请求会放在 componentWillMount 中去进行,可以提前避免白屏,这个理解是有误的:

因为Javascript中异步事件的性质,当React渲染一个组件时,它不会等待componentWillMount完成任何事情在进行下一步的处理 而是继续执行下面的代码并继续render,没有办法“暂停”渲染以等待数据到达。

而在做服务端渲染的时候我们在componentWillMount里进行异步请求,异步请求会执行两次,一次在服务端一次在客户端,这造成了多余的请求, 在React 16进行React Fiber重写后,componentWillMount可能在一次渲染中多次调用.

从而在react重写后把componentWillMount废弃,仅仅保留UNSAFE_componentWillMount

this.setState 同步还是异步?

  1. setState 只在合成事件和钩子函数中是“异步”的,在原生事件和 setTimeout 中都是同步的。
  2. setState的“异步”并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿到更新后的值,形式了所谓的“异步”,当然可以通过第二个参数 setState(partialState, callback) 中的callback拿到更新后的结果。
  3. setState 的批量更新优化也是建立在“异步”(合成事件、钩子函数)之上的,在原生事件和setTimeout 中不会批量更新,在“异步”中如果对同一个值进行多次 setState , setState 的批量更新策略会对其进行覆盖,取最后一次的执行,如果是同时 setState 多个不同的值,在更新时会对其进行合并批量更新。

react 数组中 key 的作用是什么?

我们在用react开发项目时,如果在循环一组数组去生成dom时 如果没有加上key, react会给我们一个Warning

Warning: Each child in an array or iterator should have a unique "key" prop

首先我们简单的说下react的diff算法策略,react为了提升渲染性能,使用了virutal_dom, 当渲染结构发生变化的时候,会先在virtual_dom中用diff算法进行对比,将所有的差异对比完成以后,在根据virtual_dom的变化渲染到真是dom中。而key的使用涉及到同级节点中的对比策略,当我们指定key值为我们的数据id时,diff算法会根据这个id去进行匹配,当react遍历新的dom时,发现新的dom中的key在旧的dom中存在,会认为当前节点没有发生改变或者只是移动了位置,就不会把旧的组件销毁重建。所以我们在开发中要保证key的唯一性。