24 React 一些面试题

1: React是什么

  React,用于构建用户界面的 JavaScript 库,提供了 UI 层面的解决方案,遵循组件设计模式声明式编程范式和函数式编程概念,以使前端应用程序更高效,使用虚拟DOM来有效地操作DOM,遵循从高阶组件到低阶组件的单向数据流,帮助我们将界面成了各个独立的小块,每一个块就是组件,这些组件之间可以组合、嵌套,构成整体页面.

2: React的要点和优势

  • JSX语法
  • 单向数据绑定:(在 React 中,数据仅朝一个方向流动,即从父组件流向子组件。如果数据在兄弟子组件之间共享,那么数据应该存储在父组件,并同时传递给需要数据的两个子组件。)
  • 虚拟DOM
  • 声明式编程
  • Component(组件化)
  • 高效灵活
  • 声明式的设计,简单使用
  • 组件式开发,提高代码复用率
  • 单向响应的数据流会比双向绑定的更安全,速度更快

3: Real DOM和Virtual DOM

  Real DOM,为文档对象模型,是一个结构化文本的抽象,在页面渲染出的每一个结点都是一个真实DOM结构

  • 更新缓慢
  • 可以直接更新 HTML
  • 如果元素更新,则创建新DOM
  • DOM操作代价很高
  • 消耗的内存较多

Virtual Dom,本质上是以 JavaScript 对象形式存在的对 DOM 的描述。创建虚拟DOM目的就是为了更好将虚拟的节点渲染到页面视图中,虚拟DOM对象的节点与真实DOM的属性一一照应

  • 更新更快
  • 无法直接更新 HTML
  • 如果元素更新,则更新 JSX
  • DOM 操作非常简单
  • 很少的内存消耗

4: 什么是JSX和它的特性

  JSX 是JavaScript XML的缩写,不是html或xml,基于ECMAScript的一种新特性,一种定义带属性树结构的语法;

  特性:

  •  自定义组件名首字母大写
  •  嵌套;在render函数中return返回的只能包含一个顶层标签,否则也会报错。
  •  求值表达式;JSX基本语法规则,遇到HTML标签(以<开头),就用HTML规则解析;遇到代码块(以{开头),就用JS规则解析
  •  驼峰命名
  •  class属性需要写成className
  •  JSX允许直接在模板插入JS变量。如果这个变量是一个数组,则会展开这个数组的所有成员
  •  在JSX中插入用户输入是安全的,默认情况下ReactDOM会在渲染前,转义JSX中的任意值,渲染前,所有的值都被转化为字符串形式,这能预防XSS攻击。

5:类组件和函数组件之间有什么区别

类组件:

  • 无论是使用函数或是类来声明一个组件,它决不能修改它自己的 props。
  • 所有 React 组件都必须是纯函数,并禁止修改其自身 props。
  • React是单项数据流,父组件改变了属性,那么子组件视图会更新。
  • 属性 props是外界传递过来的,状态 state是组件本身的,状态可以在组件中任意修改
  • 组件的属性和状态改变都会更新视图。

函数组件:

  • 函数组件接收一个单一的 props 对象并返回了一个React元素
  • 函数组件的性能比类组件的性能要高,因为类组件使用的时候要实例化,而函数组件直接执行函数取返回结果即可。为了提高性能,尽量使用函数组件。

6: Virtual DOM 工作原理。

  Virtual DOM 是一个轻量级 JavaScript 对象,它最初只是 real DOM 的副本。它是一个节点树,它将元素、它们的属性和内容作为对象及其属性。 React 的渲染函数从 React 组件中创建一个节点树。然后它响应数据模型中的变化来更新该树,该变化是由用户或系统完成的各种动作引起的。

  Virtual DOM 工作过程有三个简单的步骤:

  • 每当底层数据发生改变时,整个 UI 都将在 Virtual DOM 描述中重新渲染。
  • 然后计算之前 DOM 表示与新表示的之间的差异。
  • 完成计算后,将只用实际更改的内容更新 real DOM。

7: 说说对 State 和 Props的理解,有什么区别

State

  • 一个组件的显示形态可以由数据状态和外部参数所决定,而数据状态就是state,一般在 constructor 中初始化
  • 当需要修改里面的值的状态需要通过调用setState来改变,从而达到更新组件内部数据的作用,并且重新调用组件render方法
  • setState还可以接受第二个参数,它是一个函数,会在setState调用完成并且组件开始重新渲染时被调用,可以用来监听渲染是否完成

Props

  • React的核心思想就是组件化思想,页面会被切分成一些独立的、可复用的组件,组件从概念上看就是一个函数,可以接受一个参数作为输入值,这个参数就是props,所以可以把props理解为从外部传入组件内部的数据
  • react具有单向数据流的特性,所以他的主要作用是从父组件向子组件中传递数据
  • props除了可以传字符串,数字,还可以传递对象,数组甚至是回调函数
  • 在子组件中,props在内部不可变的,如果想要改变它看,只能通过外部组件传入新的props来重新渲染子组件(componentWillReceiveProps?),否则子组件的props和展示形式不会改变

相同点

  • 两者都是 JavaScript 对象
  • 两者都是用于保存信息
  • props 和 state 都能触发渲染更新

区别

  • props 是外部传递给组件的,而 state 是在组件内被组件自己管理的,一般在 constructor 中初始化
  • props 在组件内部是不可修改的,但 state 在组件内部可以进行修改
  • state 是多变的、可以修改

8: React refs 的理解,应用场景

  React 中的 Refs提供了一种方式,允许我们访问: DOM节点或在 render方法中创建的 React元素。

本质为ReactDOM.render()返回的组件实例,如果是渲染组件则返回的是组件实例,如果渲染dom则返回的是具体的dom节点。

在某些情况下,我们会通过使用refs来更新组件,但这种方式并不推荐,过多使用refs,会使组件的实例或者是DOM结构暴露,违反组件封装的原则;

但下面的场景使用refs非常有用:

  • 对Dom元素的焦点控制、内容选择、控制。
  • 对Dom元素的内容设置及媒体播放。
  • 对Dom元素的操作和对组件实例的操作。
  • 集成第三方 DOM 库。

9:setState是同步还是异步???

10:React组件生命周期有几个阶段

 初始渲染阶段:这是组件即将开始其生命之旅并进入 DOM 的阶段。

  • getDefaultProps:获取实例的默认属性
  • getInitialState:获取每个实例的初始化状态
  • componentWillMount:组件即将被装载、渲染到页面上
  • render:组件在这里生成虚拟的 DOM 节点
  • componentDidMount:组件真正在被装载之后

 更新阶段:一旦组件被添加到 DOM,它只有在 prop 或状态发生变化时才可能更新和重新渲染。这些只发生在这个阶段。

  • componentWillReceiveProps:组件将要接收到属性的时候调用
  • shouldComponentUpdate:组件接受到新属性或者新状态的时候(可以返回 false,接收数据后不更新,阻止 render 调用,后面的函数不会被继续执行了)
  • componentWillUpdate:组件即将更新不能修改属性和状态
  • render:组件重新描绘
  • componentDidUpdate:组件已经更新

 卸载阶段:这是组件生命周期的最后阶段,组件被销毁并从 DOM 中删除。

  • componentWillUnmount:组件即将销毁

详细解释 React 组件的生命周期方法

  • componentWillMount() – 在渲染之前执行,在客户端和服务器端都会执行。
  • componentDidMount() – 仅在第一次渲染后在客户端执行。
  • componentWillReceiveProps() – 当从父类接收到 props 并且在调用另一个渲染器之前调用。
  • shouldComponentUpdate() – 根据特定条件返回 true 或 false。如果你希望更新组件,请返回true ,不想更新组件则返回 false就会阻止render渲染。默认情况下,它返回 true。
  • componentWillUpdate() – 在 DOM 中进行渲染之前调用。
  • componentDidUpdate() – 在渲染发生后立即调用。
  • componentWillUnmount() – 从 DOM 卸载组件后调用。用于清理内存空间。

11: react在哪个生命周期做优化

shouldComponentUpdate,这个方法用来判断是否需要调用 render 方法重绘 dom。

因为 dom 的描绘非常消耗性能,如果我们能在这个方法中能够写出更优化的 dom diff 算法,可以极大的提高性能。

12: 受控组件和非受控组件的区别

  受控组件是:React控制的组件,input等表单输入框值不存在于 DOM 中,而是以我们的组件状态存在。每当我们想要更新值时,我们就像以前一样调用setState。

  不受控制组件:是您的表单数据由 DOM 处理,而不是React 组件,Refs 用于获取其当前值;

详情参考:【React】知识点归纳:受控组件与非受控组件区别_Dream_Lee的博客-CSDN博客

13: 为什么虚拟 dom 会提高性能

  虚拟dom(virtual dom) 是 JS对象,是一个真实dom的JS对象;虚拟 dom 相当于在 js 和真实 dom 中间加了一个缓存,利用 dom diff 算法避免了没有必要的 dom 操作,从而提高性能。

  用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异把 2 所记录的差异应用到步骤 1 所构建的真正的 DOM 树上,视图就更新了。

14:React中的key有什么作用

跟Vue一样,React 也存在diff算法,而元素key属性的作用是用于判断元素是新创建的还是被移动的元素,从而减少不必要的Diff,因此key的值需要为每一个元素赋予一个确定的标识。

  • key 应该是唯一的
  • key不要使用随机值(随机数在下一次 render 时,会重新生成一个数字)
  • 避免使用 index 作为 key??

15: react组件之间如何通信

  • 父子:父传子:props; 子传父:子调用父组件中的函数并传参;
  • 兄弟:利用redux实现和利用父组件
  • 所有关系都通用的方法:利用PubSub.js订阅

16:React context是什么

简单说就是,当你不想在组件树中通过逐层传递props或者state的方式来传递数据时,可以使用Context来实现跨层级的组件数据传递

17: Redux的原理

  redux将所有的状态进行集中管理,当需要更新状态的时候,仅需要对这个管理集中处理,而不用去关心状态是如何分发到每一个组件内部的,redux是一个实现集中管理的容器,遵循三大基本原则:单一数据源、state 是只读的、使用纯函数来执行修改;

  注意的是,redux并不是只应用在react中,还与其他界面库一起使用,如Vue。

  redux要求我们把数据都放在 store公共存储空间,一个组件改变了 store 里的数据内容,其他组件就能感知到 store的变化,再来取数据,从而间接的实现了这些数据传递的功能

18:Redux遵循的三个原则是什么

  • 单一事实来源:整个应用的状态存储在单个 store 中的对象/状态树里。单一状态树可以更容易地跟踪随时间的变化,并调试或检查应用程序。
  • 状态是只读的:改变状态的唯一方法是去触发一个动作。动作是描述变化的普通 JS 对象。就像 state 是数据的最小表示一样,该操作是对数据更改的最小表示
  • 使用纯函数进行更改:为了指定状态树如何通过操作进行转换,你需要纯函数。纯函数是那些返回值仅取决于其参数值的函数。

版权声明:本文为CSDN博主「安静、认真听」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_44182284/article/details/116979015