【React面试题总结】

1.props和state相同点和不同点?render方法在哪些情况下会执行?

不同点
1.props不可以在组件内部修改,但state可以在组件内部修改
2.可以从父组件修改自组件的props,而不能从父组件修改自组件的state
相同点
1.props和state都是导出HTML的原始数据。
2.props和state都是确定性的,如果我们写的组件为同一props和state的组合生成了不同的输出,那木我们肯定在哪里做错了
4.props和state都会触发渲染更新
5.props和state都是纯JS对象(用typeof来判断,结果都是object)
6.可以从父组件得到初始值props和state的初始值
触发时机
类组件调用 setState 修改状态
函数组件通过useState hook修改状态
一旦执行了setState就会执行render方法,useState 会判断当前值有无发生改变确定是否执行render方法,一旦父组件发生渲染,子组件也会渲染

2.shouldComponentUpdate有什么作用?

shouldComponentUpdate () 的返回值用于判断 React 组件的输出是否受当前 state 或 props 更改的影响,当 props 或 state 发生变化时,shouldComponentUpdate () 会在渲染执行之前被调用

3.说说React中的虚拟dom?在虚拟dom计算的时候diff和key之间有什么关 系?

虚拟dom理解:
实际上它只是一层对真实DOM的抽象,以JavaScript对象(VNode节点)作为基础的树,用对象的属性来描述节点,最终可以通过一系列操作时这棵树映射到真实环境上,创建虚拟DOM就是为了更好将虚拟的节点渲染到页面视图中,所以虚拟DOM对象的节点与真实DOM的属性一一照应
关系:
key 当同一层级的某个节点添加了对于其他同级节点唯一的key属性,当它在当前层级的位置发生了变化后。react diff算法通过新旧节点比较后,如果发现了key值相同的新旧节点,就会执行移动操作(然后依然按原策略深入节点内部的差异对比更新),而不会执行原策略的删除旧节点,创建新节点的操作

4.react新出来两个钩子函数是什么?和删掉的will系列有什么区别?

新生命周期中新增了两个钩子,分别为getDerivedStateFromProps(从props中得到衍生的state)和getSnapshotBeforeUpdate。

区别:

1、componentWillMount中可能需要做的事(一些数据初始化的操作就应该放在这个钩子中处理),constructor与componentDidMount也能做,甚至做的更好,此方法被废弃。
2、componentWillReceiveProps实际行为与命名并不相符,由于不稳定性已由getDerivedStateFromProps代替;
3、而componentWillUpdate同等理由被getSnapshotBeforeUpdate代替

5.React的props.children使用map函数来遍历会收到异常显示,为什么应该如何遍历?

在reactJS 中 props.children 不一定是数组,
有三种可能
1当前组件没有子节点数据类型就是undefined,
2有一个子节点数据类型就是object 。
3 有多个子节点的时候才会是array ,只有在多个节点的时候才可以直接调用map方法,react资深提供了一个react.children.map()方法,可以安全遍历子节点对象。

6.React组件之间如何通信?

  1. 父组件向子组件通讯:
    父组件可以向子组件传入props的方式,向子组件进行通讯。
  2. 子组件向父组件通讯:
    props+回调的方式,父组件向子组件传递props进行通讯,此props为作用域为父组件自身的函数,子组件调用该函数,将子组件想要传递的信息,作为参数,传递到⽗组件的作⽤域中。
  3. 兄弟组件通信:
    兄弟组件之间的传递,则父组件作为中间层来实现数据的互通,通过使用父组件传递
    例:组件A – 传值 --> 父组件 – 传值 --> 组件B
  4. 跨层级通讯:
    Context 设计⽬的是为了共享那些对于⼀个
    组件树⽽⾔是“全局”的数据,
    使用context提供了组件之间通讯的一种方式,可以共享数据,其他数据都能读取对应的数据
    例如当前认证的⽤户、主题或⾸选语⾔,对于跨越多层的全局数据通过 Context 通信再适合不过。
  5. 发布订阅者模式:
    发布者发布事件,订阅者监听事件并做出反应,我们可以通过引⼊event模块进⾏通信。
  6. 全局状态管理工具:
    借助Redux或者Mobx等全局状态管理⼯具进⾏通信,这种⼯具会维护⼀个全局状态中⼼Store,并根据不同的事件产⽣新的状态。

7.谈谈你对immutable.js的理解?

mutable.js采用了 持久化数据结构 ,保证每一个对象都是不可变的,任何添加、修改、删除等操作都会生成一个新的对象,且通过 结构共享 等方式大幅提高性能

8.redux本来是同步的,为什么它能执行异步代码?实现原理是什么?中间件的 实现原理是什么?

Redux本身是一个同步的状态管理库,但通过使用中间件(middleware),可以实现在Redux中执行异步代码。
在Redux中,中间件是一种位于action被发起和reducer处理之间的拦截器。它可以拦截action,并对其进行处理,甚至可以发起新的action。中间件提供了一种扩展Redux功能的机制,使得我们可以处理异步操作、日志记录、错误处理等。
Redux中使用中间件执行异步代码的原理是基于以下几个步骤:
**1. 创建中间件函数:**中间件函数是一个接收store对象作为参数的函数,它返回一个函数,该函数接收next作为参数。

**2. 应用中间件:**通过调用Redux的applyMiddleware函数,将中间件函数作为参数传递给它,并将返回的函数作为Redux store的enhancer。这样就将中间件应用到了Redux的执行流程中。

3. 拦截action:当发起一个action时,中间件会捕获到这个action,并在需要的情况下进行处理。中间件可以访问到当前的store对象,可以获取state、dispatch新的action等。

4. 执行异步操作:在中间件中,我们可以执行异步的操作,如发送网络请求、获取数据等。通常使用异步操作库(如axios、fetch)或者Promise来执行异步操作。

5. 发起新的action:当异步操作完成后,中间件可以根据异步操作的结果,发起新的action来更新Redux的状态。这个新的action会经过其他中间件的拦截,最终被传递给reducer进行状态更新。
通过这种方式,Redux中间件实现了在同步的Redux流程中执行异步代码的能力。它允许我们在Redux中处理异步操作,并将异步结果以同步的方式更新到状态中。
6.中间件的实现原理是,它在Redux的dispatch过程中拦截action,并可以对action进行处理、修改或者发起新的action。中间件形成了一个链式调用的机制,每个中间件都可以对action进行处理,然后将处理结果传递给下一个中间件,最终传递给reducer进行状态更新。这种链式调用的机制使得我们可以在Redux流程中插入自定义的逻辑,并对action进行灵活的处理。

9.redux中同步action与异步action最大的区别是什么?

同步: Redux的教程中反复使用todo列表的例子,那就是个典型的同步action,每当disptach action时,state就会被立即更新[当然setState是异步的]
异步: 一般异步处理都会使用中间件,比如redux-thunk或者redux-saga,他们做的事情是包装dispatch,request action由view触发,receive action由这些中间件触发

10.redux-saga和redux-thunk的区别与使用场景?

redux-thunk:通过执行action中的函数实现业务逻辑,没有拓展API
redux-saga:通过定义saga函数进行监控,同时提供一些常用的API
redux-thunk:将部分异步处理业务逻辑写在action中,redux-sagasaga则是放在监控的函数中

11.在使用redux过程中,如何防止定义的action-type的常量重复?

ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。

Symbol函数前不能使用new命令,否则会报错。这是因为生成的Symbol是一个原始类型的值,不是对象

Symbol函数可以接受一个字符串作为参数,表示对Symbol实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。

12.CDN的特点及意义?

DN的功能特点:

(1)节省骨干网带宽,减少带宽需求量;
(2)提供服务器端加速,解决由于用户访问量大造成的服务器过载问题;
(3)服务商能使用Web
Cache技术在本地缓存用户访问过的Web页面和对象,实现相同对象的访问无须占用主干的出口带宽,并提高用户访问因特网页面的相应时间的需求;
(4)能克服网站分布不均的问题,并且能降低网站自身建设和维护成本;
(5)降低“通信风暴”的影响,提高网络访问的稳定性

意义

使用CDN可以获取一些好处,无论它们是公有CDN还是提供静态内容的私有CDN,你的里程可能会有所不同,具体取决于通过CDN传递的流量以及你产生的流量。

13.为什么for循环比forEach性能高?

对于 arraylist,是顺序表,使用 for 循环可以顺序访问,速度较快;使用 foreach 会比 for 循环稍慢一些。对于 linkedlist,是单链表,使用 for 循环每次都要从第一个元素读取 next 域来读取,速度非常慢;使用 foreach 可以直接读取当前结点,数据较快;

区别:

遍历:for循环按照顺序进行遍历,forEach使用iterator迭代器遍历

数据结构:for循环是随机访问元素,foreach是顺序链表访问元素

性能上:对于数组arraylist来说,是顺序表,使用for循环可以进行顺序访问,速度比较快;使用foreach循环会比for循环稍微慢一点。对于linedlist来说,是单链表,使用for循环每次都要从第一个元素读取next域来读取,速度非常慢;使用foreach可以直接读取当前的节点,数据较快。

14.说说你对@reduxjs/toolkit的理解?和react-redux有什么区别?

react-redux 是的官方 React UI 绑定层,允许您的 React 组件从 Redux 存储中读取数据,并将操作分派到存储以更新状态。
@reduxjs/toolkit 是对 Redux 的二次封装,开箱即用可的一个高效的 Redux 开发工具集,使得创建store、更新store更加方便

15.React render方法的原理,在什么时候会触发?

原理:
在类组件中render函数指的就是render方法;而在函数组件中,指的就是整个函数组件
render函数中的jsx语句会被编译成我们熟悉的js代码,在render过程中,react将新调用的render函数返回的树与旧版本的树进行比较,这一步是决定如何更新 DOM 的必要步骤,然后进行 diff 比较,更新dom树
触发时机:
类组件调用 setState 修改状态
函数组件通过useState hook修改状态
一旦执行了setState就会执行render方法,useState 会判断当前值有无发生改变确定是否执行render方法,一旦父组件发生渲染,子组件也会渲染

16.![] == ![],![] == [],结果是什么?为什么?

结果两个 都是true

1. ![] == ![]
首先是!的优先级要比 == 高 所以 先执行两边的 ![] 然后单个的[]是true 加上!取反 也就是false了

然后 第一个 ![] == ![] 也就是等于 false == false 最后返回的是true

2. ![] == []
然后后边的![] == [] 也是因为!优先级高 所以先把左边的变成false == []

然后又因为 两个值相比较 如果有一方的值是布尔值的话 就会把另一方转成数值

然后 [] 转成数值的话 就是 0 然后因为0 = false 所以最后 也是false == false 最后也返回一个true

17.什么是闭包,应用场景是什么?

闭包的理解
闭包就是一个函数定义在另一个函数的内部 这个内部的函数就是闭包 并且闭包函数可以访问函数内部的局部变量或私有变量 并且闭包可以形成封闭私有空间 不受外部影响 还可以让变量的值始终保存到内存中
闭包使用场景 :

  • 创建私有变量
  • 延长变量的声明周期
  • 定时器传参
  • 回调和立即执行函数
  • 创建防抖,节流函数

18.谈谈你是如何做移动端适配的

  • flex弹性布局
  • 百分比
  • 用框架搭建页面
  • viewport适配
  • 媒体查询media
  • rem+viewport缩放

19.移动端1像素的解决方案

  1. 移动端1像素的解决方案?
  2. 伪类+transform
  3. viewport + rem
  4. border-image
  5. background-image
  6. postcss-write-svg

20.弹性盒中的缩放机制是怎样的

弹性盒中的项目设置flex-grow属性定义项目的放大比例,默认值为0,值越大,放大越厉害,且不支持负值;

而flex-shrink属性定义项目的缩小比例,默认值为1,数值越大,缩小越厉害,同样不支持负值;

flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间,浏览器根据这个属性,计算主轴是否有多余空间。他的默认值为auto,也就是项目的本来大小。

注意:它可以设为跟width或height属性一样的值,比如给具体的像素值,则项目将占据固定空间。

例如
弹性盒子是基于总宽度减去子元素本身占据的宽度, 剩下的宽度, 按照弹性盒子的比例去分配, 比如总宽度是1440, 子元素占据的宽度2003=600 所以可以弹性的宽度是1440-2003=840,
剩下的宽度分成4份, 840/4=210, 所以第一个div: 200+210=410, 第二个div: 200+210*2=620 第三个div和第一个一样200+210=410

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值