React面试过程中的那些事~

React作为现在前端开发领域的三大框架之一(React,Vue, Angular)广受前端同学的青睐,甚至会有一些刚步入IT行业的小白来说都会直接上手,今天我们就先来聊聊react的那些事~

  1. React的生命周期都有哪些?
    首先我们先来看一下React的整体生命周期图

    Constructor:是ES6对类的默认方法,通过new命令生成对象实例时自动调用该方法。并且,该方法是类中必须有的,如果没有定义,则会默认添加空的constructor()方法,当存在constructor的时候⚠️必须在constructor函数里面调用super方法。在constructor中  如果要使用this.props需要传入props,在super()被调用之前,子类是不能使用this的,在ES2015中,子类必须在constructor中调用super(),传递props给super()的原因则是便于(在子类中)能在constructor访问this.props
    示例如下:
    Class TestComponent extends Component {
        constructor(props) {
            super(props)
            this.state = {
                list: this.props.list
            }
        }
    }

     

    1. ComponentWillMount()组件挂载前
      在组件挂载前调用且全局只调用一次,如果在这个钩子里可以setState,render后可以看到更新后的state,不会触发重复渲染,该生命周期可以发起异步请求并进行setState(React在V16.3以后便废弃该钩子函数,可以在组件声明的时候constructor函数里面对state进行初始化)

    2. render()渲染组件
      render是一个React组件必须定义的生命周期,用来渲染DOM。⚠️不要在render里面修改state,会触发死循环导致栈溢出,render必须返回reactDOM

    3. componentDidMount()组件挂载后
      在组件挂载完成后调用且全局只调用一次,可以在这里使用refs,获取真实DOM,该钩子内也可以发起异步请求并在异步请求中可以进行setState

    4. componentWillReceiveProps(nextProps)props即将变化之前
      props发生变化以及父组件重新渲染时都会触发该生命周期,在该钩子内可以通过参数nextProps获取变化后的props参数,通过this.props访问之前的props,该生命周期内可以进行setState

    5. shouldComponentUpdate(nextProps, nextState)是否重新渲染
      组件挂载之后,每次调用setState以后都会调用shouldComponentUpdate判断是否需要重新渲染组件,默认返回true,需要重新render,返回false则不触发重发渲染,在比较复杂的应用里,有一些数据的改变并不影响界面的展示,可以在这里做判断,优化渲染效率

    6. componentWillUpdate(nextProps,nextState)
      shouldComponentUpdate返回true或者调用forceUpdate之后,componentWillupdate会被调用,不能把在该钩子中setState,会触发重复循环(React v16.3后废弃该生命周期,可以用新的周期 getSnapshotBeforeUpdate )

    7. componentDidUpdate()完成组件渲染
      除了首次调用componentDidMount,其他render结束之后都是调用componentDidUpdate,该钩子内setState又可能会触发重复渲染,需要自行判断,否则会进入死循环

    8. componentWillUnMount()组件即将被卸载
      组件被卸载的时候调用,一般在componentDidMount里面注册的事件需要在这里面删除

    9. React v16.3 新加入的生命周期 (转载)
      react v16.3删掉以下三个生命周期
      componentWillMount
      componentWillReceiveProps
      componentWillUpdate
      新增两个生命周期
      static getDerivedStateFromProps
      getSnapshotBeforeUpdate
      static getDerivedStateFromProps
      触发时间:在组件构建之后(虚拟dom之后,实际dom挂载之前) ,以及每次获取新的props之后。
      每次接收新的props之后都会返回一个对象作为新的state,返回null则说明不需要更新state.
      配合componentDidUpdate,可以覆盖componentWillReceiveProps的所有用法

      class Example extends React.Component {
        static getDerivedStateFromProps(nextProps, prevState) {
          // 没错,这是一个static
        }
      }

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

      class Example extends React.Component {
          getSnapshotBeforeUpdate(prevProps, prevState) {
          // ...
          }
      }

       

  2. Raect中key的作用是什么?
    key是React用于追踪哪些列表中的元素被修改、被添加或者被移除的辅助标识

    render() {
        return (
            <div>
                {
                    this.state.todoItem.map((item, index) => {
                        return <li key={index}>{item}</li>
                    })
                }
            </div>
        )
    }

    在开发的过程中,我们需要保证某个元素的key的在其同级元素中具有唯一性。在React Diff算法中React会借助元素的key值来判断该元素是最新被创建的还是被移动而来的,从而减少不必要的元素重新渲染。此外,React还需要借助Key值来判断元素与本地状态的关联关系,因此我们绝不可忽略转换函数中key的重要性

  3. 调用setState之后发生了什么?
    在代码中调用setState函数之后,React会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation)。经过调和过程,React会以相对高效的方式根据新的状态构建React元素树并且着手重新渲染整个UI界面。在React得到元素树之后,React会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染。在差异计算算法中,React能够相对精确的知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。

  4. React Diff原理,为什么虚拟DOM就可以提高性能
    原理:把树形结构按照层级分解,只比较同级元素;给列表结构的每个单元添加唯一的key属性,方便比较;React只会匹配相同class的component(这里的class指的是组件的名字);合并操作,调用component的setState方法的时候,React将其标记为dirty,到每一个事件循环结束,React检查所有标记dirty的component重新绘制;选择性子树渲染,开发人员可以重写shouldComponentUpdate提高diff的性能
    虚拟DOM:虚拟dom相当于在js和真实dom中间加了一个缓存,利用dom diff算法避免了没有必要的dom操作,从而提高性能。用JavaScript对象结构标识DOM树的结构;然后用这个树构建一个真正的DOM树,插到文档当中当状态变更的时候,重新构造一课新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异把2所记录的差异应用到步骤1所构建的真正的DOM树上,视图就更新了

  5. React中refs的作用是什么?
    Refs是React提供给我们的安全访问DOM元素后者某个组件实例的句柄。我们可以为元素添加ref属性然后在回调函数中接受该元素在DOM树中的句柄,该值会作为回调函数的第一个参数返回:

    class CustomForm extends Component {
      handleSubmit = () => {
        console.log("Input Value: ", this.input.value)
      }
      render () {
        return (
          <form onSubmit={this.handleSubmit}>
            <input
              type='text'
              ref={(input) => this.input = input} />
            <button type='submit'>Submit</button>
          </form>
        )
      }
    }

    上述代码中的input域包含了一个ref属性,该属性声明的回调函数会接收input对应的DOM元素,我们将其绑定到this指针以便在其他的类函数中使用。另外值得一提的是,refs并不是类组件的专属,函数式组件同样能够利用必报暂存其值:

    function CustomForm ({handleSubmit}) {
      let inputElement
      return (
        <form onSubmit={() => handleSubmit(inputElement.value)}>
          <input
            type='text'
            ref={(input) => inputElement = input} />
          <button type='submit'>Submit</button>
        </form>
      )
    }

     

  6. (组件的)状态state和属性props之间有何不同?
    state是一种数据结构,用于组件挂载时所需数据的默认值。State可能会随着时间的推移而发生改变,但多数时候是作为用户事件行为的结果
    props则是组件的配置。props由父组件传递给子组件,并且就子组件而言,props是可不变的。组件不能改变自身的props,但是可以把其子组件的props放在一起(统一管理)。Props也不仅仅是数据-回调函数也可以通过props传递

  7. 简述flux思想
    Flux的最大特点就是数据的“单向流动”
    a.用户访问view
    b.View发出用户的Action
    c.Dispatcher收到Action,要去store进行相应的更新
    d.Store更新后,发出一个“change”事件
    e.View收到“change”事件后,更新页面









     

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值