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的实现原理

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

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

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

十五:react-saga的设计思想

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

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

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

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

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

二十一:ssr

原文地址:https://www.cnblogs.com/jcxfighting/p/11681992.html

时间: 2024-10-04 07:27:36

react相关面试题的相关文章

Java集合类相关面试题

1.Collection和Collections的区别 java.util.Collection 是一个集合接口,Collection接口在Java类库中有很多具体的实现,例如List.Set java.util.Collections 是针对集合类的一个帮助类,它提供了一系列的静态方法实现对各种集合的搜索.排序.线程安全化等操作. 2.ArrayList与Vector的区别 这两个类都实现了List接口(List接口继承自Collection接口).它们都是有序集合,它们内部的元素都是可以重复

黑马程序员----java学习笔记之数组、二维数组,附相关面试题

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------- 一:数组(掌握) (1)数组:存储同一种数据类型的多个元素的容器. (2)特点:每一个元素都有编号,从0开始,最大编号是长度-1. 编号的专业叫法:索引 (3)定义格式 A:数据类型[] 数组名; B:数据类型 数组名[]; 推荐是用A方

Linux相关面试题&amp;答案

Linux相关面试题&答案 Linux面试题&答案 假设apache日志格式为:118.78.199.98 – - [09/Jan/2010:00:59:59 +0800] "GET /Public/Css/index.css HTTP/1.1″ 304 – "http://www.a.cn/common/index.php" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; GTB6.

react相关问题

什么是JSX?--浏览器是如何识别它的? JSX是facebook普及的一种标记语言,通过babel/TSC等工具会编译为React.createElementfunction.所以在React每个组件中,虽然没有显式用到React,但都需要import React from 'react'. JSX是如何区分React Component和HTML元素的? 通过元素首字母的大小写,如果首字母大写,则认为是React组件,小写的话则会被认为是HTML元素.可以在online Babel comp

黑马程序员----java基础----继承与多态,附相关面试题

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一:继承(掌握) (1)把多个类中相同的成员给提取出来定义到一个独立的类中.然后让这多个类和该独立的类产生一个关系, 这多个类就具备了这些内容.这个关系叫继承. (2)Java中如何表示继承呢?格式是什么呢? A:用关键字extends表示 B:格式: class 子类名 extends 父类名 {} (3)继承的好处: A:提高了代码的复用性 B:提高了代码的维护性 C:让类与类产生了一个关

每天五个java相关面试题(1)--struts2部分

好啦 好啦.过不了多久我要参加社招啦,每天在博客更新五个java方面的面试题以及参考回答的答案. 最近先来框架部分. 首先是struts2: 开始! 1.Struts2工作机制? 答: 1.客户端初始化一个指向Servlet容器(例如Tomcat)的请求: 2.这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin): 3.接着FilterD

java面试题全集(中)--Java Web和Web Service相关面试题

这部分主要是与Java Web和Web Service相关的面试题. 96.阐述Servlet和CGI的区别? 答:Servlet与CGI的区别在于Servlet处于服务器进程中,它通过多线程方式运行其service()方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于Servlet. 补充:Sun Microsystems公司在1996年发布Servlet技术就是为了和CGI进行竞争,Servlet是一个特殊的Java程

Struts2相关面试题(转)

Struts2面试题 1.struts2工作流程 Struts 2框架本身大致可以分为3个部分: 核心控制器FilterDispatcher.业务控制器Action和用户实现的企业业务逻辑组件. 核心控制器FilterDispatcher是Struts 2框架的基础, 包含了框架内部的控制流程和处理机制. 业务控制器Action和业务逻辑组件是需要用户来自己实现的. 用户在开发Action和业务逻辑组件的同时,还需要编写相关的配置文件, 供核心控制器FilterDispatcher来使用. St

每天五个java相关面试题(10)--java基础详解篇2

好勒好勒.一起加油 一.HashMap和Hashtable的区别. 答: HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable. HashMap允许将null作为一个entry的key或者value,而Hashtable不允许. HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey.因