• react面试题总结一波,以备不时之需


    React组件的构造函数有什么作用?它是必须的吗?

    构造函数主要用于两个目的:

    • 通过将对象分配给this.state来初始化本地状态
    • 将事件处理程序方法绑定到实例上

    所以,当在React class中需要设置state的初始值或者绑定事件时,需要加上构造函数,官方Demo:

    class LikeButton extends React.Component {
       
      constructor() {
       
        super();
        this.state = {
       
          liked: false
        };
        this.handleClick = this.handleClick.bind(this);
      }
      handleClick() {
       
        this.setState({
       liked: !this.state.liked});
      }
      render() {
       
        const text = this.state.liked ? 'liked' : 'haven\'t liked';
        return (
          <div onClick={
       this.handleClick}>
            You {
       text} this. Click to toggle.      </div>
        );
      }
    }
    ReactDOM.render(
      <LikeButton />,
      document.getElementById('example')
    );
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    构造函数用来新建父类的this对象;子类必须在constructor方法中调用super方法;否则新建实例时会报错;因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法;子类就得不到this对象。

    注意:

    • constructor () 必须配上 super(), 如果要在constructor 内部使用 this.props 就要 传入props , 否则不用
    • JavaScript中的 bind 每次都会返回一个新的函数, 为了性能等考虑, 尽量在constructor中绑定事件

    除了在构造函数中绑定 this,还有其它方式吗

    你可以使用属性初始值设定项(property initializers)来正确绑定回调,create-react-app 也是默认支持的。在回调中你可以使用箭头函数,但问题是每次组件渲染时都会创建一个新的回调。

    什么原因会促使你脱离 create-react-app 的依赖

    当你想去配置 webpack 或 babel presets。

    何为 action

    Actions 是一个纯 javascript 对象,它们必须有一个 type 属性表明正在执行的 action 的类型。实质上,action 是将数据从应用程序发送到 store 的有效载荷。

    diff算法如何比较?

    • 只对同级比较,跨层级的dom不会进行复用
    • 不同类型节点生成的dom树不同,此时会直接销毁老节点及子孙节点,并新建节点
    • 可以通过key来对元素diff的过程提供复用的线索
    • 单节点diff
    • 单点diff有如下几种情况:
    • key和type相同表示可以复用节点
    • key不同直接标记删除节点,然后新建节点
    • key相同type不同,标记删除该节点和兄弟节点,然后新创建节点

    组件通信的方式有哪些

    • ⽗组件向⼦组件通讯: ⽗组件可以向⼦组件通过传 props 的⽅式,向⼦组件进⾏通讯
    • ⼦组件向⽗组件通讯: props+回调的⽅式,⽗组件向⼦组件传递props进⾏通讯,此props为作⽤域为⽗组件⾃身的函 数,⼦组件调⽤该函数,将⼦组件想要传递的信息,作为参数,传递到⽗组件的作⽤域中
    • 兄弟组件通信: 找到这两个兄弟节点共同的⽗节点,结合上⾯两种⽅式由⽗节点转发信息进⾏通信
    • 跨层级通信: Context 设计⽬的是为了共享那些对于⼀个组件树⽽⾔是“全局”的数据,例如当前认证的⽤户、主题或⾸选语⾔,对于跨越多层的全局数据通过 Context 通信再适合不过
    • 发布订阅模式: 发布者发布事件,订阅者监听事件并做出反应,我们可以通过引⼊event模块进⾏通信
    • 全局状态管理⼯具: 借助Redux或者Mobx等全局状态管理⼯具进⾏通信,这种⼯具会维护⼀个全局状态中⼼Store,并根据不同的事件产⽣新的状态

    参考 前端进阶面试题详细解答

    什么是受控组件和非受控组件

    • 受控组件:

      没有维持自己的状态

      数据由付组件控制

      通过props获取当前值,然后通过回调函数通知更改

    • 非受控组件

      保持这个自己的状态

      数据有DOM控制

      refs用于获取其当前值

    React的虚拟DOM和Diff算法的内部实现

    传统 diff 算法的时间复杂度是 O(n^3),这在前端 render 中是不可接受的。为了降低时间复杂度,react 的 diff 算法做了一些妥协,放弃了最优解,最终将时间复杂度降低到了 O(n)。

    那么 react diff 算法做了哪些妥协呢?,参考如下:

    1. tree diff:只对比同一层的 dom 节点,忽略 dom 节点的跨层级移动

    如下图,react 只会对相同颜色方框内的 DOM 节点进行比较,即同一个父节点下的所有子节点。当发现节点不存在时,则该节点及其子节点会被完全删除掉,不会用于进一步的比较。

    这样只需要对树进行一次遍历,便能完成整个 DOM 树的比较。

    image-20210302195610674

    这就意味着,如果 dom 节点发生了跨层级移动,react 会删除旧的节点,生成新的节点,而不会复用。

    1. component diff:如果不是同一类型的组件,会删除旧的组件,创建新的组件

    image-20210302195654736

    1. element diff:对于同一层级的一组子节点,需要通过唯一 id 进行来区分
    • 如果没有 id 来进行区分,一旦有插入动作,会导致插入位置之后的列表全部重新渲染
    • 这也是为什么渲染列表时为什么要使用唯一的 key。

    React如何获取组件对应的DOM元素?

    可以用ref来获取某个子节点的实例,然后通过当前class组件实例的一些特定属性来直接获取子节点实例。ref有三种实现方法:

    • 字符串格式:字符串格式,这是React16版本之前用得最多的,例如:&l

  • 相关阅读:
    华为OD 机智的外卖员(100分)【java】A卷+B卷
    【龙芯固件】ACPI表中I2C资源
    Vue.js核心技术解析与uni-app跨平台实战开发学习笔记 第5章 Vue.js组件 5.1 创建全局组件
    Generator函数和yield的说明
    数据分析 第一周 折线图笔记
    d八月会议
    MyBatis-Plus分页查询
    详述MIMIC 的ICU患者检测时间信息表(十六)
    中国城市中心点坐标
    闪马智能完成4亿元第四轮融资 国产自主可控AI平台加速赋能城市升级
  • 原文地址:https://blog.csdn.net/beifeng11996/article/details/128214119