• react相关面试题


    React 的核心流程可以分为两个部分:

    reconciliation (调度算法,也可称为 render): // 调和

        更新 state 与 props;

        调用生命周期钩子;

        生成 virtual dom;

        这里应该称为 Fiber Tree 更为符合;

        通过新旧 vdom 进行 diff 算法,获取 vdom change;

        确定是否需要重新渲染

      commit:

        如需要,则操作 dom 节点更新;

    constructor ====》 初始化state
    componentWillMount  ==== 》getDerivedStateFromProps // 当新 props 中的 data 发生变化时,同步更新到 state 上
    componentDidMount ====》进行事件监听,数据的请求
    componentWillUpdate === 》 getSnapshotBeforeUpdate componentDidUpdate ==== 》 当 id 发生变化时,重新获取数据 shouldComponentUpdate ====》 优化渲染的性能,return false 阻止后面的逻辑 componentWillReciveProps ==== 》少使用,使用getDerivedStateFromProps  componentWillUnmount ====》 解绑事件

    在新版本中,React 官方对生命周期有了新的 变动建议:

    • 使用getDerivedStateFromProps 替换componentWillMount
    • 使用getSnapshotBeforeUpdate替换componentWillUpdate
    • 避免使用componentWillReceiveProps

    其实该变动的原因,正是由于上述提到的 Fiber。首先,从上面我们知道 React 可以分成 reconciliation 与 commit 两个阶段,对应的生命周期如下:

    • reconciliation:

      • componentWillMount
      • componentWillReceiveProps
      • shouldComponentUpdate
      • componentWillUpdate
    • commit:

      • componentDidMount
      • componentDidUpdate
      • componentWillUnmount

    在 Fiber 中,reconciliation 阶段进行了任务分割,涉及到 暂停 和 重启,因此可能会导致 reconciliation 中的生命周期函数在一次更新渲染循环中被 多次调用 的情况,产生一些意外错误。

    新版的建议生命周期如下:

    class Component extends React.Component {
      // 替换 `componentWillReceiveProps` ,
      // 初始化和 update 时被调用
      // 静态函数,无法使用 this
      static getDerivedStateFromProps(nextProps, prevState) {}
      
      // 判断是否需要更新组件
      // 可以用于组件性能优化
      shouldComponentUpdate(nextProps, nextState) {}
      
      // 组件被挂载后触发
      componentDidMount() {}
      
      // 替换 componentWillUpdate
      // 可以在更新之前获取最新 dom 数据
      getSnapshotBeforeUpdate() {}
      
      // 组件更新后调用
      componentDidUpdate() {}
      
      // 组件即将销毁
      componentWillUnmount() {}
      
      // 组件已销毁
      componentDidUnMount() {}
    }
    

      使用建议:

    • constructor初始化 state;
    • componentDidMount中进行事件监听,并在componentWillUnmount中解绑事件;
    • componentDidMount中进行数据的请求,而不是在componentWillMount
    • 需要根据 props 更新 state 时,使用getDerivedStateFromProps(nextProps, prevState)
      • 旧 props 需要自己存储,以便比较;
      • public static getDerivedStateFromProps(nextProps, prevState) {
        	// 当新 props 中的 data 发生变化时,同步更新到 state 上
        	if (nextProps.data !== prevState.data) {
        		return {
        			data: nextProps.data
        		}
        	} else {
        		return null1
        	}
        }
        

          

    • 可以在componentDidUpdate监听 props 或者 state 的变化,例如:
    componentDidUpdate(prevProps) {
    	// 当 id 发生变化时,重新获取数据
    	if (this.props.id !== prevProps.id) {
    		this.fetchData(this.props.id);
    	}
    }
    

     

    • componentDidUpdate使用setState时,必须加条件,否则将进入死循环;
    • getSnapshotBeforeUpdate(prevProps, prevState)可以在更新之前获取最新的渲染数据,它的调用是在 render 之后, update 之前;
    • shouldComponentUpdate: 默认每次调用setState,一定会最终走到 diff 阶段,但可以通过shouldComponentUpdate的生命钩子返回false来直接阻止后面的逻辑执行,通常是用于做条件渲染,优化渲染的性能。

    二: 虚拟DOM的理解

      (1)Virtual DOM是对DOM的抽象,本质上是JavaScript对象,这个对象就是更加轻量级的对DOM的描述.

        (2)两个内容的差异,进行dom的对比,事件属性方法,耗性能,dom对象转换为js对象,比较会快。有效提升性能。

      (3)首先,我们都知道在前端性能优化的一个秘诀就是尽可能少地操作DOM,不仅仅是DOM相对较慢,更因为频繁变动DOM会造成浏览器的回流或者重回,这些都是性能的杀手,因此我们需要这一层抽象,在patch过程中尽可能地一次性将差异更新到DOM中,这样保证了DOM不会出现性能很差的情况.

        (4)更好的跨平台,比如Node.js就没有DOM,如果想实现SSR(服务端渲染),那么一个方式就是借助Virtual DOM,因为Virtual DOM本身是JavaScript对象.

    三:diff算法

      (1)diff的目的就是比较新旧Virtual DOM Tree找出差异并更新.

      (2)一层节点发现有问题,不再往下比,直接放弃,n的平方降低为n

    • 把树形结构按照层级分解,只比较同级元素(层级比较)
    • 给列表结构的每个单元添加唯一的 key 属性,方便比较(列表添加key)
    • React 只会匹配相同 class 的 component(这里面的 class 指的是组件的名字)
    • 选择性子树渲染。开发人员可以重写shouldComponentUpdate 提高 diff 的性能

    四:key值的作用

      (1)如果key值相同,dom直接复用,不用再创建dom,直接这两个比,不用循环比

      (2)用新指针对应节点的key去旧数组寻找对应的节点,这里分三种情况,

          当没有对应的key,那么创建新的节点,

          如果有key并且是相同的节点,把新节点patch到旧节点,

          如果有key但是不是相同的节点,则创建新节点

    五:怎么理解HOC高阶组件

       接收一些函数,返回函数,组件进行包装,返回一个新的组件,很多地方都要用,有一点区别,共用的东西写在高阶组件中,通过传递额外参数,动态改变组件不同场景下使用的差异。

    六:redux中间件的原理

      action--store-reducer-props   action和store之间,沟通的桥梁dispatch,改装dispatch,

      store.dispatch,直接把action(对象)传递给store,使用中间件,action可以是函数,可以将函数转换为对象,传递给store。

    七:setState发生了什么?遇到过什么坑

      调和的过程。setState一般怎么用,传递什么进去,对象还是方法。

    this.setState({
        name: '小李'
    });
    this.setState(() =>({
        name:'小李'
    }));
    永远用函数调用,会避免一些坑。
    this.setState({
        age: this.state.age+1
    });
    setState异步,疯狂点击按钮,age不是每次加1,会一次加5,6个,state异步,会进行累加
    <input  refs="input"  value={this.state.age} />  ====1 
    this.setState((prevState) =>{
        age: ++ prevState
    });
    this.refs.input.value  ==== 1
    this.setState((prevState) =>{
        age: ++ prevState
    }, () => {
        this.refs.input.value  // 异步执行完state之后执行
    });

    八:ref是一个函数,有什么好处?

      方便react在销毁组件重新渲染,有效清空ref引用中的东西,防止内存泄漏

    九:refs作用是什么,在什么场景下用过?

      操作dom(滚动条,点击按钮,滚动条滚动到上面)

      图片展示获取图片的宽和高,

    十:react中this的指向问题

      

    十一:react-router的实现原理

    hash/location

    十二:jsx代码的转化(babel)

    createElement

    十三:受控组件和非受控组件

    受控:有生命周期

    非受控:纯函数

    十四:函数组件怎么做性能优化

    十五:react-saga的设计思想

    改装dispatch   action-----store之间,action可以是一个函数,可以执行异步操作

    十六:组件是什么?类是什么?类被编译成什么?

    十七:reselect是做什么使用的?

    十八:什么时候使用异步组件?

    十九:xss攻击,react如何防范?

    二十:react怎么提高性能优化?

    shouldComponentUpdate

    pureComponent

    二十一:ssr

    二十二:

    • 为什么返回多个标签或组件必须要用一个标签或组件包裹?
    • 为什么在根本没有使用React这个变量的情况下还要import React

    整个UI实际上是通过层层嵌套的React.createElement方法返回的,所以我们要在文件开头import React,否则编译后就会发现createElement没有定义。

    React.createElement执行的结果是一个对象,对象的属性描述了标签或组件的性状,对象再嵌套子对象。如果顶层返回多个标签,就无法表达为一个对象了

  • 相关阅读:
    LeetCode 295. Find Median from Data Stream (堆)
    LeetCode 292. Nim Game(博弈论)
    《JavaScript 模式》读书笔记(4)— 函数2
    《JavaScript 模式》读书笔记(4)— 函数1
    《JavaScript 模式》读书笔记(3)— 字面量和构造函数3
    《JavaScript 模式》读书笔记(3)— 字面量和构造函数2
    《JavaScript 模式》读书笔记(3)— 字面量和构造函数1
    《JavaScript 模式》读书笔记(2)— 基本技巧3
    《JavaScript 模式》读书笔记(2)— 基本技巧2
    《JavaScript 模式》读书笔记(2)— 基本技巧1
  • 原文地址:https://www.cnblogs.com/jcxfighting/p/11681992.html
Copyright © 2020-2023  润新知