React,Redux面试题

这里写目录标题

react 合成事件

由于react中存在一个根标签,所以在react中给元素所绑定的事件,其实并不是直接绑定在元素本身,而是通过事件合成绑定在了这个根标签上,通过冒泡事件触发,每当有事件注册时,react内部就会创建一个映射表,将事件和触发事件的元素进行绑定,当触发事件后,根标签捕捉到事件,通过映射表给对应的元素委派事件,在最新版本的react中,捕获阶段时合成事件要先于原生事件执行,在冒泡阶段,原生事件先执行,有的时候我们的事件会执行两次就是因为存在这个事件合成的机制。

react 虚拟dom
虚拟DOM是一个特殊的JS对象,它描述的是真实的dom结构,类似于dom树,但他不是真实的DOM,所以叫做虚拟DOM,虚拟DOM的好处是可以通过一些特殊的算法,用来减少对真实DOM的操作次数,提高性能。

谈谈你对react fiber 结构理解
Fiber 是现在react中核心的算法,它的出现是为了解决以前js引擎和渲染引擎互斥,一个执行另一个会被挂起等待,有的时候会由于js引擎算法过于复杂导致页面加载时间过长,它可以把一个渲染任务分解为多个渲染任务,而不是一次性完成,把每一个分割得很细的任务视作一个"执行单元",React 就会检查现在还剩多少时间,如果没有时间就将控制权让出去,故任务会被分散到多个帧里面,中间可以返回至主进程控制执行其他任务,最终实现更流畅的用户体验。


一、react 中key是什么 有什么作用?

key是什么

  1. key是react用来追踪哪些列表的元素被修改,被添加或者是被删除的辅助标示。在开发过程中我们需要保证某个元素的key在其同级元素中具有唯一性。

  2. 如果列表数据渲染中,在数据后面插入一条数据,key作用并不大,前面的元素在diff算法中,前面的元素由于是完全相同的,并不会产生删除创建操作,在最后一个比较的时候,则需要插入到新的DOM树中

key作用

  1. react中key的作用是:在diff算法中判断元素是最新创建的还是被移动来的,从而减少不必要的diff,也就是为了提高diff同级比较的效率,避免原地复用带来的副作用;key是react用来追踪列表的元素被修改,被添加或者是被删除的标识。

注意事项为:

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

二、组件通信有哪些方式?

1).父传子props

父组件通过props的方式向子组件传递数据,但是props是单向绑定,只能是父组件向子组件传递

2).子传父

在父组件中定义回调函数,加在子组件的属性上,子组件调用该方法给父组件传递数据

3).非嵌套组件通信Context和props 逐层传递

  1. context是一个全局变量,像是一个大容器,在任何地方都可以访问到,我们可以把要通信的信息放在context上,然后在其他组件中可以随意取到。
  2. 但是React官方不建议使用大量context,尽管他可以减少逐层传递,但是当组件结构复杂的时候,我们并不知道context是从哪里传过来的;当传递内容很多时可以考虑redux。
  3. 传递方式:提供者
  4. 接收方式:1.contextType => 提供者value 2.消费者 =>提供者value

三、路由组件传值

  1. useParams 作用:获取params参数,返回,参数独享

  2. search参数

    • useSearchParams()作用:获取seach参数,返回值:数组

    • 0: 参数对象, .get(key) 获取具体参数

    • 1: setSearch() 更改search 参数


四、react合成事件机制

React 自己实现了这么一套事件机制,它在 DOM 事件体系基础上做了改进,减少了内存的消耗,并且最大程度上解决了 IE 等浏览器的不兼容问题

那它有什么特点?

  • React 上注册的事件最终会绑定在document这个 DOM 上,而不是 React 组件对应的 DOM(减少内存开销就是因为所有的事件都绑定在 document 上,其他节点没有绑定事件)
  • React 自身实现了一套事件冒泡机制,所以这也就是为什么我们 event.stopPropagation() 无效的原因。
  • React 通过队列的形式,从触发的组件向父组件回溯,然后调用他们 JSX 中定义的 callback
  • React 有一套自己的合成事件 SyntheticEvent,不是原生的,这个可以自己去看官网
  • React 通过对象池的形式管理合成事件对象的创建和销毁,减少了垃圾的生成和新对象内存的分配,提高了性能

五、函数组件和class组件如何选择

类式组件的功能更为完整,它存在函数式组件不存在的一些生命周期钩子,比如在组件挂在前执行的钩子,在组件更新前执行的钩子,还存在错误边界钩子,当有这些特殊需求时,只能选择使用类式组件,

但在平常开发中推荐使用函数式组件,因为函数式组件没有this,所以不需要自己手动绑定this,操作更为简便,再函数式组件有了hook之后功能基本上和类式组件没有差别,而且函数式组件更好拆分,更适合模块化的开发


六、react路由模式有哪些?

路由存在history模式和hash模式


七、说说对React的理解?有哪些特性?

React是什么:

  • 用于构建用户界面的 JavaScript 库,提供了 UI 层面的解决方案

  • 遵循组件设计模式、声明式编程范式和函数式编程概念,以使前端应用程序更高效

  • 使用虚拟DOM来有效地操作DOM,遵循从高阶组件到低阶组件的单向数据流

  • 帮助我们将界面成了各个独立的小块,每一个块就是组件,这些组件之间可以组合、嵌套,构成整体页面

  • react 类组件使用一个名为 render() 的方法或者函数组件return,接收输入的数据并返回需要展示的内容

React特性:

  • JSX语法
  • 单向数据绑定
  • 虚拟DOM
  • 声明式编程
  • Component

优势:

  • 高效灵活
  • 声明式的设计,简单使用
  • 组件式开发,提高代码复用率
  • 单向响应的数据流会比双向绑定的更安全,速度更快

八、虚拟DOM(Virtual DOM)和真实DOM(Real DOM)区别

虚拟DOM(Virtual DOM)

  • 虚拟DOM是以Javascript的形式存在来描述DOM,创建虚拟DOM的目的就是将虚拟DOM更好的渲染到页面UI中,它与真实的DOM是一一对应的
  • 不可以直接更新HTML
  • 元素更新,更新JSX
  • 操作DOM方便,消耗少的内存,更新快

真实DOM(Real DOM)

  • 真实的DOM类似于一个文档对象模型,页面上渲染出来的节点都是真实的DOM
  • 可以直接更新HTML
  • 元素更新,创建新的DOM
  • 操作DOM比较麻烦,消耗很大的内存

虚拟dom原理流程

  • 用JavaScript模拟DOM树,并渲染这个DOM树

  • 比较新老DOM树,得到比较的差异对象

  • 把差异对象应用到渲染的DOM树


九、什么是JSX和它的特性?

JSX是什么:

  • JSX就是Javascript和XML结合的一种格式。是 JavaScript 的语法扩展,只要你把HTML代码写在JS里,那就是JSX。

  • 在实际开发中,JSX 在产品打包阶段都已经编译成纯 JavaScript,不会带来任何副作用,反而会让代码更加直观并易于维护。官方定义是:类 XML 语法的 ECMAScript 扩展

特点:

  • JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
  • 它是类型安全的,在编译过程中就能发现错误。
  • 使用 JSX 编写模板更加简单快速

十、说说对 State 和 Props的理解,有什么区别?

  1. props是组件对外的接口,用于组件之间的传值,props在组件内部是不可修改,可以看作只读属性。

  2. state可以看作组件的私有属性,用于组件内部的数据传递。

  3. state可在组件内进行修改,state初始化的地方是在constructor()构建函数中,组件内修改必须使用setState()函数。

  4. 说到setState()不得不再啰嗦几句。react的面试面试官经常会问setState()是同步还是异步?既然这么问了那当然是异步啦。

  5. setState是异步更新,同步执行,因为react中会将多个setState合并在一起处理,从而提升程序的性能,这就是react高明的其中一点。

  6. 所以在编写程序时我们不能依赖于当前的state去计算下一个state。因为异步所以this.state不一定是最新的组件属性值。

  7. 对于以上问题是否有解决办法?那肯定有呀。

  8. 既然是异步,那肯定就有回调函数,说到回调函数相比大家都知道解决办法啦。

  9. 那setState()函数的回调函数在哪呢,这个大家应该都知道,但是我就是想写。

  10. setState()函数有两个参数,第一个我就不赘述了,第二个就是它的回调啦。


十一、说说对React refs 的理解?应用场景?

refs是什么:

  • Refs 在计算机中称为弹性文件系统(英语:Resilient File System,简称ReFS)

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

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

创建ref的形式:

  • 传入字符串,使用时通过 this.refs.传入的字符串的格式获取对应的元素

  • 传入对象,对象是通过 React.createRef() 方式创建出来,使用时获取到创建的对象中存在 current 属性就是对应的元素

  • 传入函数,该函数会在 DOM 被挂载时进行回调,这个函数会传入一个 元素对象,可以自己保存,使用时,直接拿到之前保存的元素对象即可

  • 传入hook,hook是通过 useRef() 方式创建,使用时通过生成hook对象的 current 属性就是对应的元素

应用场景:
在某些情况下,我们会通过使用refs来更新组件,但这种方式并不推荐,更多情况我们是通过props与state的方式进行去重新渲染子元素过多使用refs,会使组件的实例或者是DOM结构暴露,违反组件封装的原则例如,避免在 Dialog 组件里暴露 open() 和 close() 方法,最好传递 isOpen 属性但下面的场景使用refs非常有用:

  • 对Dom元素的焦点控制、内容选择、控制

  • 对Dom元素的内容设置及媒体播放

  • 对Dom元素的操作和对组件实例的操作

  • 集成第三方 DOM 库


十二、super()和super(props)有什么区别?

  • 在ES6中,通过super关键字实现调用父类,super代替的是父类的构建函数;

  • 在React中,类组件是基于es6的规范实现的,继承React.Component,因此如果用到constructor就必须写super()才初始化this,这时候,在调用super()的时候,我们一般都需要传入props作为参数,如果不传进去,React内部也会将其定义在组件实例中

// React 内部
const instance = new YourComponent(props);
instance.props = props;
  • 所以无论有没有constructor,在render中this.props都是可以使用的,这是React自动附带的,是可以不写的

十三、说说对React事件机制的理解?

React 有一套自己的事件系统,其事件叫做合成事件。

React 事件概述

React 根据W3C 规范来定义自己的事件系统,其事件被称之为合成事件 (SyntheticEvent)。而其自定义事件系统的动机主要包含以下几个方面:

(1)抹平不同浏览器之间的兼容性差异。最主要的动机。

(2)事件"合成",即事件自定义。事件合成既可以处理兼容性问题,也可以用来自定义事件(例如 React 的 onChange 事件)。

(3)提供一个抽象跨平台事件机制。类似 VirtualDOM 抽象了跨平台的渲染方式,合成事件(SyntheticEvent)提供一个抽象的跨平台事件机制。

(4)可以做更多优化。例如利用事件委托机制,几乎所有事件的触发都代理到了 document,而不是 DOM 节点本身,简化了 DOM 事件处理逻辑,减少了内存开销。(React 自身模拟了一套事件冒泡的机制)

(5)可以干预事件的分发。V16引入 Fiber 架构,React 可以通过干预事件的分发以优化用户的交互体验。

注:「几乎」所有事件都代理到了 document,说明有例外,比如、标签的一些媒体事件(如 onplay、onpause 等),是 document 所不具有,这些事件只能够在这些标签上进行事件进行代理,但依旧用统一的入口分发函数(dispatchEvent)进行绑定。


十四、React事件绑定的方式有哪些?区别?

  • 由于类的方法默认不会绑定this,因此在调用的时候如果忘记绑定,this的值将会是undefined
    通常如果不是直接调用,应该为方法绑定this。

4种方式绑定this

  • 在构造函数中使用bind绑定this

  • 在调用的时候使用bind绑定this

  • 在调用的时候使用箭头函数绑定this

  • 在声明方法的时候使用箭头方法绑定this

几种方式的区别

  1. 在调用的使用绑定this,我们可以采用bind(this)及()=>(this.xxx())绑定的方式;优点:简单;缺点:每次渲染生成,降低性能;
  2. 在初始化的绑定this,我们可以在constructor中及使用xxx = () => {} 这样来绑定; 优点:只生成一次;缺点:代码多点;

总结:建议使用xxx = () => {}定义方法,这样性能最佳,使用也相对方便;


十五、React组件生命周期有几个阶段

React的生命周期分为两种情况,一种是16.3版本前的,还有一种是16.3版本后的,本着早写晚写都要写的原则,

第一种生命周期:

Initialization:初始化阶段**

  • 检查组件中是否含有默认属性,是否有属性校验

Mounting:挂载阶段

  • constructor:构造函数,它是React生命周期的一部分,,在这里面定义各种state,以及要绑定的函数
  • componentWillMount:此时页面即将挂载到页面了(类似beforeMount),React官方不推荐在这里发送AJAX请求,在这里也可以进行一些setState的操作。
  • render:执行render函数渲染页面,主要做一些数据渲染,展示。这里不能调用setState,因为setState会再次render页面,从而又一次render到了函数内,发现了setState,如此往复,陷入死循环。
  • componentDidMount:此时函数已经被挂载到了页面中。在这里可以进行发送AJAX,setState等个各种对页面的操作

Updation:更新阶段

  • componentWillReceiveProps:在组件接收到新的Props前被调用,基本上没啥作用。这是只针对props单独写的生命周期函数
  • shouldComponentUpdate:判断组件是否需要被更新,它会接受两个参数,nextProps,nextStates,这个生命周期函数需要返回一个boolean值,默认是true,如果返回值为false,那么不更新
  • componentWillUpdate:组件更新前被调用,这里也不能使用setState,此时会回到showComponentUpdate的死循环中。基本上没啥用
  • render:同Monuting阶段的render
  • componentDidUpdate:告知组件更新并渲染完毕,此时更新完的组件已经渲染到页面。此时也不能设置ajax和setState。(这个生命周期中的大坑,当时我就在这里面写过,导致整个功能无法运行)

Unmounting:卸载阶段

  • componentWillUnmount:组件销毁时候调用,此时可以在这里销毁各种诸如定时器等需要销毁的函数

第二种生命周期

相比于16.3版本之前的生命周期,新的生命周期将所有的will的生命周期都删除了个干净,此外新加了getDerviedStateFromProps和getSnapshotBeforeUpdate。

  • getDerviedStateFromProps
    • 触发时间:组件每次被render的时候,包括在组件构建之后(虚拟dom之后,实际dom挂载之前),每次获取新的props或state之后。
    • 每次接收一个新的props之后都会返回一个对象作为新的state,返回null则说不需要更新
    • 这是个静态方法,所以没有this
  • getSnapshotBeforeUpdate
    • 触发时间:update发生的时候,在render之后,组件的dom被渲染之前
    • 返回一个值,作为componentDidUpdate的第三个参数 如此我们把目前所有的生命周期都理一遍: 目前react生命周期总共分为三个部分:挂载阶段,更新阶段,卸载阶段;

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

  • getDerviedStateFromProps
    • 触发时间:组件每次被render的时候,包括在组件构建之后(虚拟dom之后,实际dom挂载之前),每次获取新的props或state之后。
    • 每次接收一个新的props之后都会返回一个对象作为新的state,返回null则说不需要更新
    • 这是个静态方法,所以没有this
  • getSnapshotBeforeUpdate
    • 触发时间:update发生的时候,在render之后,组件的dom被渲染之前
    • 返回一个值,作为componentDidUpdate的第三个参数 如此我们把目前所有的生命周期都理一遍: 目前react生命周期总共分为三个部分:挂载阶段,更新阶段,卸载阶段;
  1. 挂载阶段:

    • constructor:实例化阶段,在里面设置各种state,function
    • getDeriverdStateFromProps:从props中获取state
    • render:渲染整个组件
    • componentDidMount:挂载完成,可以在这个上面写各种请求
  2. 更新阶段:

    • getDeriverdStateFromProps:从props中获取state
    • shouldComponentUpdate:判断组件是否需要重新渲染
    • render:渲染整个组件
    • getSnapshotBeforeUpdate:获取渲染前的样子,作为componentDidUpdate的第三个参数
    • componentDidUpdate:组件更新完毕
  3. 卸载阶段:

    • componentWillUnmount:组件卸载前调用
  4. 错误处理:

    • getDerviedtateFromError:从错误中获取state

    • componentDidCatch:捕获错误并进行处理


十七、react vue angular 如何选择

  1. 当开发的页面使用的是一个单页面切数据量庞大的时候可以选择使用react
  2. 轻量、小型、数据量少的项目可以采用vue
  3. angular的语法规则较为严格,而且项目体积较大,相比快捷跟react和vue确实没什么竞争力,不过由于语法较为严格,bug出错的可能性也较低

十八、受控组件和非受控组件的区别

React中的组件根据是否受React控制可分为受控的(controlled)和非受控的(uncontrolled)。

多数情况下,推荐使用受控组件实现表单。在受控组件中,表单数据由组件控制。

另外一种是非受控组件,这种方式下表单组件由DOM自身控制。

受控组件

  1. 受控组件通过props获取其当前值,并通过回调函数(比如onChange)通知变化

  2. 表单状态发生变化时,都会通知React,将状态交给React进行处理,比如可以使用useState存储

  3. 受控组件中,组件渲染出的状态与它的valuechecked属性相对应

  4. 受控组件会更新state的流程

非受控组件

非受控组件将数据存储在DOM中,而不是组件内,这比较类似于传统的HTML表单元素。

  1. 非受控组件的值不受组件自身的stateprops控制
  2. 非受控组件使用refDOM中获取元素数据

十九、React组件事件代理的原理

React 基于 Virtual DOM 实现了一个 SyntheticEvent 层(合成事件层), 定义的事件处理器会接收到一个合成事件对象的实例, 它符合 W3C 标准, 且与原生的浏览器事件拥有同样的接口, 支持冒泡机制, 所有的事件都自动绑定在最外层上。

在 React 底层, 主要对合成事件做了两件事:

事件委派: React 会把所有的事件绑定到结构的最外层, 使用统一的事件监听器, 这个事件监听器上维持了一个映射来保存所有组件内部事件监听和处理函数

自动绑定: React 组件中, 每个方法的上下文都会指向该组件的实例, 即自动绑定 this 为当前组件


二十、为什么虚拟 dom 会提高性能

虚拟dom(virtual dom) 其实就是一个JavaScript对象,通过这个JavaScript对象来描述真实dom。

真实dom

以前没有虚拟dom,如果需要比较两个页面的差异,我们需要通过对真实dom进行比对。真实dom节点是非常复杂的,它里面会绑定的事件,它会有属性,背后会有各种方法,会频繁触发重排与重绘,所以两个真实dom比对,非常耗性能。 总损耗 = 真实DOM完全增删改 + (可能较多的节点)重排与重绘

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

总损耗 = 虚拟DOM增删改 + (与Diff算法效率有关)真实DOM差异增删改 + (较少的节点)重排与重绘

具体实现步骤如下:

  1. 用JavaScript对象结构表示DOM树的结构;然后用这个树构建一个真正的DOM树,插到文档当中;

  2. 当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异;

  3. 把步骤2所记录的差异应用到步骤1所构建的真正的DOM树上,视图就更新了。


二十一、什么是高阶组件?

高阶组件就是一个函数,且该函数接受一个组件作为参数,并返回一个新的组件。基本上,这是从React的组成性质派生的一种模式,我们称它们为 “纯”组件, 因为它们可以接受任何动态提供的子组件,但它们不会修改或复制其输入组件的任何行为。

  • 高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧
  • 高阶组件的参数为一个组件返回一个新的组件
  • 组件是将 props 转换为 UI,而高阶组件是将组件转换为另一个组件

二十二、说说对React Hooks的理解?解决了什么问题?

一、、是什么
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性

  • 至于为什么引入hook,官方给出的动机是解决长时间使用和维护react过程中常遇到的问题,例如:

  • 难以重用和共享组件中的与状态相关的逻辑

  • 逻辑复杂的组件难以开发与维护,当我们的组件需要处理多个互不相关的 local state 时,每个生命周期函数中可能会包含着各种互不相关的逻辑在里面

  • 类组件中的this增加学习成本,类组件在基于现有工具的优化上存在些许问题

  • 由于业务变动,函数组件不得不改为类组件等等

  • 在以前,函数组件也被称为无状态的组件,只负责渲染的一些工作

  • 因此,现在的函数组件也可以是有状态的组件,内部也可以维护自身的状态以及做一些逻辑方面的处理

二、有哪些

上面讲到,Hooks让我们的函数组件拥有了类组件的特性,例如组件内的状态、生命周期

最常见的hooks有如下:

  • useState

  • useEffect

  • 其他


二十三、说说react中引入css的方式有哪几种?区别?

常见的CSS引入方式有以下:

  • 在组件内直接使用
  • 组件中引入 .css 文件
  • 组件中引入 .module.css 文件 (将css文件作为一个模块引入,这个模块中的所有css,只作用于当前组件。不会影响当前组件的后代组件)
  • CSS in JS (是指一种模式,其中CSS由 JavaScript生成而不是在外部文件中定义)

区别:

  • 在组件内直接使用css该方式编写方便,容易能够根据状态修改样式属性,但是大量的演示编写容易导致代码混乱
  • 组件中引入 .css 文件符合我们日常的编写习惯,但是作用域是全局的,样式之间会层叠
  • 引入.module.css 文件能够解决局部作用域问题,但是不方便动态修改样式,需要使用内联的方式进行样式的编写
  • 通过css in js 这种方法,可以满足大部分场景的应用,可以类似于预处理器一样样式嵌套、定义、修改状态等

二十四、在React中组件间过渡动画如何实现?

react中,react-transition-group是一种很好的解决方案,其为元素添加enterenter-activeexitexit-active这一系列勾子,可以帮助我们方便的实现组件的入场和离场动画

其主要提供了三个主要的组件:

  • CSSTransition:在前端开发中,结合 CSS 来完成过渡动画效果
  • SwitchTransition:两个组件显示和隐藏切换时,使用该组件
  • TransitionGroup:将多个动画组件包裹在其中,一般用于列表中元素的动画

二十五、介绍Redux中间件

Redux-thunk 是 redux 的中间件。

  • 它主要设计用来处理项目中的异步操作,如获取接口数据等。

  • 过去异步操作都会写在组件中,请求到数据再创建 action。这使得异步操作遍布很多组件文件中,维护不便,且不易于自动化测试。

Redux-thunk 主要理念是:将所有异步操作都放在 action 里面去处理,与业务组件代码解耦。而要实现这个理念,需要 action 处理异步逻辑,需要它是一个函数。

实现逻辑:

  • Redux-thunk 处于 action 与 store 之间。扩展了 dispatch 函数,在原有功能之余增加了新的逻辑:若入参是函数,则直接执行。
  • 如此,使得原本只能为 object 的 action 可以作为 function 处理更多逻辑。
  • Redux-thunk 没有提供很多 api,它的使用较为简单,就是在 action 中可以处理更多逻辑。

二十六、React context是什么?

Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。在一个典型的 React 应用中,数据是通过 props 属性自上而下(由父及子)进行传递的,但这种做法对于某些类型的属性而言是极其繁琐的(例如:地区偏好,UI 主题),这些属性是应用程序中许多组件都需要的。Context 提供了一种在组件之间共享此类值的方式,而不必显式地通过组件树的逐层传递 props。

使用方法:

  • React.createContext:创建一个装上下文的容器组件,defaultValue 可以设置需要共享的默认数据;只有在没有被 Provider 容器包裹下的组建使用 context,默认值才会生效;
  • Context.Provider:提供者,用于提供共享数据的地方,value 属性设置什么数据就共享什么数据;
  • Context.Consumer:消费者,专门消费 Provider 提供的共享数据,Consumer 需要嵌套在 Provider 下面,才能通过回调的方式拿到共享的数据;(只有函数组件会用到)
  • Class.contextType:记住是用于指定 contextType 等于当前的 context,必须指定,才能通过 this.context 来访问到共享的数据;(只有类组件会用到)
  • Context.displayName:context 对象接收一个名为 displayName 的属性,类型为字符串。React DevTools 使用该字符串来确定 context 要显示的内容。

二十七、说说你对Redux的理解?其工作原理?

react是用于搭建页面的,解决渲染DOM的过程,但是整个页面中会有很多组件,每个组件的state都是自身管理,这样写着没有问题,但是在开发和后期维护阶段就显得比较繁琐,而redux可以对所有的状态进行集中管理,这样需要更新状态的时候,只需要对这个管理集中处理就行

工作原理:

  • store 一个单一的数据源(里面存放了state),注意它是只读的
  • Action 对变化的描述。函数返回值为 {type,data},支持同步,异步
  • Reducer 一个函数,负责对变化(也就是action)进行分发和处理,最终把最新的数据返回给Store

把Ui组件比作买奶茶的,store就是收银员,action就是订单,Reducer 就是后面做饮料的小伙子,state就是你的饮料

首先ui组件去买饮料会先对store说自己想喝什么,store就会拿着订单active给后面做饮料的小伙子reducer,做完后reducer会把饮料给收银员,输入state

转换为代码是,Ui组件 需要获取一些数据, 然后它就告知 Store 需要获取数据,这就是就是 Action , Store 接收到之后让 Reducer 弄一下, Reducer 就会知道 Store 想要什么数据


二十八、Redux遵循的三个原则是什么?

redux就是一个实现上述集中管理的容器,遵循三大基本原则:

  • 单一事实来源:

    ​ 整个应用的状态存储在单个 store 中的对象/状态树里。单一状态树可以更容易地跟踪随时间的变化,并调试或检查应用程序。

  • 状态是只读的:

    ​ 改变状态的唯一方法是去触发一个动作。动作是描述变化的普通 JS 对象。就像 state 是数据的最小表示一样,该操作是对数据更改的最小表示。

  • 使用纯函数进行更改:

    ​ 为了指定状态树如何通过操作进行转换,你需要纯函数。纯函数是那些返回值仅取决于其参数值的函数


二十九、react-redux的两个最主要功能?

react-redux,我们便不再需要使用store的subscribe自己去订阅状态了。UI组件就像普通组件一样内部没有redux的身影。可读性更高。

react-redux将组件分为UI组件和容器组件,UI组件只负责UI的呈现,不带有任何业务逻辑,通过props接收数据,不使用Rdux的API,一般保存在components文件夹下,容器组件,只负责管理数据和业务逻辑,不负责UI的呈现,使用redux的API,一般保存在containers文件夹下。


三十、Redux中异步的请求怎么处理

使用redux的redux-thunk插件来处理

createStore里的第二个参数放入applyMiddleware(thunk)这样就可以解决异步

import {createStore,applyMiddleware,combineReducers} from 'redux'
import thunk from 'redux-thunk'
import countReducer from './count_reducer'

// combineReducers 用来访问多个请求
let routReducer = combineReducers({
    count:countReducer,
})

export default createStore(routReducer,applyMiddleware(thunk))

三十一、你在React项目中是如何使用Redux的? 项目结构是如何划分的?

首先我们要知道什么的react-redux

redux是用于数据状态管理,而react是一个视图层面的库,如果将两者连接在一起,可以使用官方推荐react-redux库,其具有高效且灵活的特性

react-redux将组件分成:

  • 容器组件:存在逻辑处理

  • UI 组件:只负责现显示和交互,内部不处理逻辑,状态由外部控制

通过redux将整个应用状态存储到store中,组件可以派发dispatch行为action给store

其他组件通过订阅store中的状态state来更新自身的视图

如何做,使用方法

使用react-redux分成了两大核心:

  • Provider 在redux中存在一个store用于存储state,如果将这个store存放在顶层元素中,其他组件都被包裹在顶层元素之上

  • connection 将store上的getStatedispatch包装成组件的props

<Provider store = {store}>
    <App />
<Provider>
// 创建容器组件,建立容器组件与Ui组件的联系
import { connect } from "react-redux";
connect(
    state => ({			 // mapStateToProps方法   把redux中的数据映射到react中的props中去
        count: state,   
    }),
    dispatch => ({ 			// mapDispatchToProps方法	将redux中的dispatch映射到组件内部的props中
        onClick:data=>dispatch(createAddCount(data)),
    })
)(Count)

三、项目结构

可以根据项目具体情况进行选择,以下列出两种常见的组织结构

按角色组织(MVC)

  • reducers
  • actions
  • components
  • containers

按功能组织

使用redux使用功能组织项目,也就是把完成同一应用功能的代码放在一个目录下,一个应用功能包含多个角色的代码

Redux中,不同的角色就是reduceractions和视图,而应用功能对应的就是用户界面的交互模块

每个功能模块对应一个目录,每个目录下包含同样的角色文件:

  • actionTypes.js 定义action类型

  • actions.js 定义action构造函数

  • reducer.js 定义这个功能模块如果响应actions.js定义的动作

  • views 包含功能模块中所有的React组件,包括展示组件和容器组件

  • index.js 把所有的角色导入,统一导出


三十二、为什么 React Router 中使用 Switch 关键字 ?

由于router和switch对于路由的渲染策略不同,对router来说,如果有的链接既可以被路由A匹配,又可以被路由B匹配,那么Router会同时渲染它们

对于switch来说,它只会渲染符合条件的第一个路径,避免重复匹配

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
关于React面试,有以下几个方面的内容可以被问到: 1. 常见面试:这些问通常涉及React的基础知识,如React组件是什么,React中的状态管理是如何实现的等等。[1] 2. React组件面试:这些问涉及React组件的特性和用法,例如函数组件和类组件的区别,如何在组件之间传递数据等等。 3. React Redux面试:这些问关于使用ReactRedux进行状态管理的技术,如何在React中使用Redux,如何处理异步操作等等。 4. React Router面试:这些问涉及React Router库的使用,如何实现路由导航和参数传递等等。 5. HTML CSS JS免费实战学习:这些问可能与前端开发的基础知识和实践有关,如HTML和CSS的基本概念,如何使用JavaScript进行交互等等。 总结起来,React相关的面试主要涉及React的基础知识、组件使用、状态管理、路由导航以及与前端开发相关的技术。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [面试整理|50个React面试及解析](https://blog.csdn.net/pengxian00007/article/details/117752084)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [【前端面试】—30道常见React基础面试(附答案)](https://blog.csdn.net/snsHL9db69ccu1aIKl9r/article/details/115339484)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值