资讯专栏INFORMATION COLUMN

React专题:react,redux以及react-redux常见一些面试题

darcrand / 773人阅读

摘要:我们可以为元素添加属性然后在回调函数中接受该元素在树中的句柄,该值会作为回调函数的第一个参数返回。使用最常见的用法就是传入一个对象。单向数据流,比较有序,有便于管理,它随着视图库的开发而被概念化。

面试中问框架,经常会问到一些原理性的东西,明明一直在用,也知道怎么用,
但面试时却答不上来,也是挺尴尬的,就干脆把react相关的问题查了下资料,再按自己的理解整理了下这些答案。
react生命周期有哪些

组件载入阶段:
componentWillMount:组件即将被装载、渲染到页面上,只调用1次
componentDidMount:组件真正在被装载之后,这里可以拿到真实DOM执行操作,只调用1次

运行中状态:
componentWillReceiveProps(nextProps):组件将要接收到新属性的时候调用,在这时setState不会触发额外的render,因为此时已经有一次来自父组件引发的render了。

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

销毁阶段:
componentWillUnmount:组件即将销毁,这时候可以销毁绑定的事件监听或者定时器什么的。

有些好像把render也算进生命周期了:
render:组件在这里生成虚拟的 DOM 节点

react在哪个生命周期做优化

shouldComponentUpdate,这个方法用来判断是否需要调用 render 方法重绘 dom。
因为 dom 的描绘非常消耗性能,如果我们能在这个方法中能够写出更优化的 dom diff 算法,可以极大的提高性能。

react的diff算法是怎么完成的
1.把树形结构按照层级分解,只比较同级元素。
2.通过给列表结构的每个单元添加的唯一 key值进行区分同层次的子节点的比较。
3.React 只会匹配相同 class 的 component(这里面的 class 指的是组件的名字)
4.合并操作,调用 component 的 setState 方法的时候, React 将其标记为 dirty.
    到每一个事件循环结束, React 检查所有标记 dirty 的 component 重新绘制。
5.选择性渲染。开发人员可以重写 shouldComponentUpdate 提高 diff 的性能。


图片源自:react精髓之一---diff算法

react虚拟DOM实现原理,以及为什么虚拟 dom 会提高性能

实现原理:

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

原因:虚拟 dom 相当于在 js 和真实 dom 中间加了一个缓存,利用 dom diff 算法减少了对真实DOM的操作次数,从而提高性能。
react怎么从虚拟dom中拿出真实dom

Refs 是 React 提供给我们的安全访问 DOM 元素或者某个组件实例的句柄。
我们可以为元素添加 ref 属性然后在回调函数中接受该元素在 DOM 树中的句柄,该值会作为回调函数的第一个参数返回。或者ref可以传字符串。

例如:{return this.name=input}) />, this.name.value取值
或者 ,this.refs.name取值

React中的props和state的用法

state 是一种数据结构,用于组件挂载时所需数据的默认值。state 可能会随着时间的推移而发生突变,但多数时候是作为用户事件行为的结果。
Props则是组件的配置。props 由父组件传递给子组件,并且就子组件而言,props 是不可变的(immutable)

react组件之间如何通信

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

react的setState的原理及用法

原理:当调用setState时,它并不会立即改变,而是会把要修改的状态放入一个任务队列,等到事件循环结束时,再合并指更新。
因此,setState有 异步,合并更新更新两个特性。

这里应该需要了解下Batch Update 。

使用:
1.最常见的用法就是传入一个对象。

    this.setState({
        isLoading:false
    })

2.还可以接收一个函数

    this.setState((prevState,props)=>{
        // 要做的事件
        return {isLoading:false};
    })

3.因为setState是异步的,所以它还可以接收第二个参数,一个回调函数

    this.setState({count:2},()=>{
        isLoading:this.state.count===2 ? true : false
    })
setState为什么是异步的
参考链接:React 中 setState() 为什么是异步的?、 react的setstate原理

1.保证内部的一致性

因为props是要等到父组件渲染过后才能拿到,也就是不能同步更新,state出于统一性设成异步更新。

2.性能优化

举例说你正在一个聊天窗口输入,如果来了一条新消息又要render,那就会阻塞你的当前操作,导致延迟什么的。

3.支持state在幕后渲染

异步可以使state在幕后更新,而不影响你当前旧的页面的交互,提升用户体验。

详情可以点击上面的参考链接,写的很详细的。

另外:setstate在原生事件,setTimeout,setInterval,promise等异步操作中,state会同步更新

react的优势以及特点

优势:

1. 实现对虚拟DOM的操作,使得它速度快,提高了Web性能。
2. 组件化,模块化。react里每一个模块都是一个组件,组件化开发,可维护性高。
3. 单向数据流,比较有序,有便于管理,它随着React视图库的开发而被Facebook概念化。
4. 跨浏览器兼容:虚拟DOM帮助我们解决了跨浏览器问题,它为我们提供了标准化的API,甚至在IE8中都是没问题的。

不足:

1. react中只是MVC模式的View部分,要依赖引入很多其他模块开发。、
2. 当父组件进行重新渲染操作时,即使子组件的props或state没有做出任何改变,也会同样进行重新渲染。

特点: 

1. 声明式设计:React采用声明范式,可以轻松描述应用。
2. 高效:React通过对DOM的模拟,最大限度地减少与DOM的交互。
3. 灵活:React可以与已知的库或框架很好地配合。
React如何性能优化

讲一些项目中用到的小的点:

1. 充分利用shouldComponentUpdate函数,不过这需要你的组件尽量最小化,如果当前组件数据过于复杂,其实是很难优化的。
2. 给你的DOM遍历上加上唯一的key,注意尽量不要用index,因为如果你新DOM中删了某一个节点,它会重新排列index,
那跟原来同层级一比就都会完全不一样,而重新渲染了,所以最好使用id值什么的作key值。

3. 能用const声明的就用const。
4. DOM里少用箭头函数,当然其实要传参时也还是得用。再者,函数bind尽量写在constructor,避免每次render重新bind。
5. 减少对真实DOM的操作。
6. 如果是用webpack搭建环境的话,当一个包过大加载过慢时,可分打成多个包来优化。
react-perf性能查看工具,可自行了解下:react-perf
react与vue的对比
有些是个人意见,仅供参考。

相同点:

1. 都用虚拟DOM实现快速渲染
2. 我觉得父子,兄弟通信这些都挺像的,也都有自己的状态管理器:react=>redux, vue=>vuex
3. 都是轻量级框架
4. 现在vue也在渐渐吸收react中的一些语法,比如JSX语法,类式声明写法等

不同点:

1. React属于单向数据流——MVC模式,vue则属于双向——MVVM模式。
2. react兼容性比vue好,vue不兼容IE8.
3. react采用JSX语法,vue采用的则是html模板语法。
4. vue的css可以有组件的私有作用域,react则没有。
5. react比vue好的另一点是,它是团队维护,而vue属于个人,一般来说,大型项目更倾向于react,小型则用vue,当然这也不是绝对。

Redux的实现流程

用户页面行为触发一个Action,然后,Store 自动调用 Reducer,并且传入两个参数:当前 State 和收到的 Action。Reducer 会返回新的 State 。每当state更新之后,view会根据state触发重新渲染。

react-redux的实现原理

Redux作为一个通用模块,主要还是用来处理应用中state的变更,通过react-redux做连接,可以在React+Redux的项目中将两者结合的更好。
react-redux是一个轻量级的封装库,它主要通过两个核心方法实现:

Provider:从最外部封装了整个应用,并向connect模块传递store。
Connect: 
    1、包装原组件,将state和action通过props的方式传入到原组件内部。
    2、监听store tree变化,使其包装的原组件可以响应state变化
redux中间件的理解,以及用过哪些中间件

理解:中间件就是要对redux的store.dispatch方法做一些改造,以实现其他的功能。

我用过redux-thunk,就拿它举例。

背景:Redux 的基本做法,是用户发出 Action,Reducer 函数立刻算出新的 State,View 重新渲染,但这是做同步。

而如果有异步请求时,那就不能知道什么时候获取的数据有存进store里面,因此此时需要在请求成功时返回一个标识或状态,并在此时再触发action给reducer传值。
因此,为了解决异步的问题,就引入了中间件的概念。

作用: redux-thunk 帮助你统一了异步和同步 action 的调用方式,把异步过程放在 action 级别解决,对 component 调用没有影响。

引入使用可参照:理解redux和redux的中间件redux-thunk的认识
redux-thunk VS redux-saga对比 异步处理方案中间件
原文链接:异步方案选型redux-saga 和 redux-thunk

redux-thunk
缺点:

(1).一个异步请求的action代码过于复杂,且异步操作太分散,相对比saga只要调用一个call方法就显得简单多了。
(2).action形式不统一,如果不一样的异步操作,就要写多个了。

优点:学习成本低

redux-saga:
优点:

(1)集中处理了所有的异步操作,异步接口部分一目了然(有提供自己的方法)
(2)action是普通对象,这跟redux同步的action一模一样({type:XXX})
(3)通过Effect,方便异步接口的测试
(4)通过worker和watcher可以实现非阻塞异步调用,并且同时可以实现非阻塞调用下的事件监听
(5) 异步操作的流程是可以控制的,可以随时取消相应的异步操作。

缺点:学习成本高。

比较redux和vuex的区别

原文链接不记得了(囧...)
相同点:

1.数据驱动视图,提供响应式的视图组件
2.都有virtual DOM, 组件化开发,通过props参数进行父子组件数据的传递,都实现webComponents规范
3.都支持服务端渲染  
4.都有native解决方案,reactnative(facebook团队) vs weex(阿里团队)

不同点:

1.vuex是一个针对VUE优化的状态管理系统,而redux仅是一个常规的状态管理系统(Redux)与React框架的结合版本。
2.开发模式:React本身,是严格的view层,MVC模式;Vue则是MVVM模式的一种方式实现
3.数据绑定:Vue借鉴了angular,采取双向数据绑定的方式;React,则采取单向数据流的方式
4.数据更新:Vue采取依赖追踪,默认是优化状态:按需更新;
    React在则有两种选择:
    1)手动添加shouldComponentUpdate,来避免冗余的vdom,re-render的情况
    2)Components 尽可能都用 pureRenderMixin,然后采用 redux 结构 + Immutable.js
5.社区:react相比来讲还是要大于vue,毕竟背后支撑团队不同。
    facebook vs 个人!当然目前vue的增长速度是高于react的增速,不知道未来的发展趋势是如何。

总之:期待构建一个大型应用程序——选择React,期待应用尽可能的小和快——选择Vue
react-router的实现原理

原理:实现URL与UI界面的同步。其中在react-router中,URL对应Location对象,
而UI是由react components来决定的,这样就转变成location与components之间的同步问题。

优点:

1.风格: 与React融为一体,专为react量身打造,编码风格与react保持一致,例如路由的配置可以通过component来实现
2.简单: 不需要手工维护路由state,使代码变得简单
3.强大: 强大的路由管理机制,体现在如下方面
4.路由配置: 可以通过组件、配置对象来进行路由的配置
5.路由切换: 可以通过 Redirect进行路由的切换
6.路由加载: 可以同步记载,也可以异步加载,这样就可以实现按需加载
7.使用方式: 不仅可以在浏览器端的使用,而且可以在服务器端的使用

缺点:API不太稳定,在升级版本的时候需要进行代码变动。

react router3到4有什么改变

我只挑了一部分。
原文链接:https://blog.csdn.net/qq_3548...

1. V4不再使用V3里的{props.children}(代表所有路由-个人理解),而V4丢给 DOM 的是我们的应用程序本身.
2. V4还同时支持同时渲染多个路由,1和2都可参照下面代码,当访问 /user 时,两个组件都会被渲染。(V3可实现但过程复杂)
  
Our React Router 4 App
;
3.获取路由的路径匹配,可以使用props.match.path获取,match上还有match.params,match.url等属性。
注:url是浏览器的url的一部分,path是给router写的路径
4.多了一个限制未登录的用户访问某些路由功能,可以在应用程序顶端中设置一个主入口,区别登录和未登录UI展示界面。

对webpack的理解:
参考链接:webpack配置整理

概念: webpack是一个预编译模块方案,它会分析你的项目结构将其打包成适合浏览器加载的模块。
打包原理:把所有依赖打包成一个bundle.js文件,通过代码分割成单元片段并按需加载。
核心思想:

1.一切皆模块,一个js,或者一个css文件也都看成一个模块,
2.按需加载,传统的模块打包工具(module bundlers)最终将所有的模块编译生成一个庞大的bundle.js文件。
    但是在真实的app里边,“bundle.js”文件可能有10M到15M之大可能会导致应用一直处于加载中状态。
    因此Webpack使用许多特性来分割代码然后生成多个“bundle”文件,而且异步加载部分代码以实现按需加载。

基础配置项:

1. entry:{} 入口,支持多入口
2. output 出口
3. resolve 处理依赖模块路径的解析
4. module 处理多种文件格式的loader
5. plugins 除了文件格式转化由loader来处理,其他大多数由plugin来处理
6. devServer 配置 webpack-dev-server
7. 搭配package.json配置环境变量,以及脚本配置。
"scripts": {
    "build": "webpack --mode production",
    "start": "webpack-dev-server --mode development"
}

"scripts": {
    "build_": "NODE_ENV=production webpack",
    "start_": "NODE_ENV=development webpack-dev-server"
}
react高阶组件
参考资料:浅谈React高阶组件 
通俗理解 React 高阶函数
深入浅出React高阶组件
定义:js里的高阶函数的定义是接收一个函数作为参数,并返回一个函数。redux的connect就是一个高阶函数。
那react高阶组件就是指接收一个react组件作为入参,并返回一个新react组件的组件。

好处:它不用关心组件从哪来,也就是不用自己去引入很多个组件了。
一个简单的高阶组件:(写法不是唯一)

    export default function withHeader(WrappedComponent){
        return class HOC extends component{
            return (
                
这是一段普通的文字
) } } 直接引入:import withHeader from "withHeader"

高阶组件部分还有待补充。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99385.html

相关文章

  • 常见react面试汇总(适合中级前端)

    摘要:但在中会有些不同,包含表单元素的组件将会在中追踪输入的值,并且每次调用回调函数时,如会更新,重新渲染组件。在构造函数中调用的目的是什么在被调用之前,子类是不能使用的,在中,子类必须在中调用。将使用单个事件监听器监听顶层的所有事件。 已经开源 地址:https://github.com/nanhupatar...关注我们团队:showImg(https://segmentfault.co...

    leone 评论0 收藏0
  • 前端最实用书签(持续更新)

    摘要:前言一直混迹社区突然发现自己收藏了不少好文但是管理起来有点混乱所以将前端主流技术做了一个书签整理不求最多最全但求最实用。 前言 一直混迹社区,突然发现自己收藏了不少好文但是管理起来有点混乱; 所以将前端主流技术做了一个书签整理,不求最多最全,但求最实用。 书签源码 书签导入浏览器效果截图showImg(https://segmentfault.com/img/bVbg41b?w=107...

    sshe 评论0 收藏0
  • 深入理解js

    摘要:详解十大常用设计模式力荐深度好文深入理解大设计模式收集各种疑难杂症的问题集锦关于,工作和学习过程中遇到过许多问题,也解答过许多别人的问题。介绍了的内存管理。 延迟加载 (Lazyload) 三种实现方式 延迟加载也称为惰性加载,即在长网页中延迟加载图像。用户滚动到它们之前,视口外的图像不会加载。本文详细介绍了三种延迟加载的实现方式。 详解 Javascript十大常用设计模式 力荐~ ...

    caikeal 评论0 收藏0
  • Redux:实用

    摘要:在英文中的意思是有效载荷。有一个动作被发射了顾名思义,替换,这主要是方便开发者调试用的。相同的输入必须返回相同的输出,而且不能对外产生副作用。怎么办呢开发者得手动维护一个订阅器,才能监听到状态变化,从而触发页面重新渲染。 本文是『horseshoe·Redux专题』系列文章之一,后续会有更多专题推出来我的 GitHub repo 阅读完整的专题文章来我的 个人博客 获得无与伦比的阅读体...

    Big_fat_cat 评论0 收藏0
  • React-redux基础

    摘要:简介创建的函数,返回一个对象,包含等方法合并多个中间件处理,在实际的前调用一系列中间件,类似于绑定和函数式编程中常见的方法,介绍官方提供的绑定库。 前言 在学习了React之后, 紧跟着而来的就是Redux了~ 在系统性的学习一个东西的时候, 了解其背景、设计以及解决了什么问题都是非常必要的。接下来记录的是, 我个人在学习Redux时的一些杂七杂八~ Redux是什么 通俗理解 h...

    jsyzchen 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<