目录
- 1.React 中 keys 的作用是什么?
- 2.调用 setState 之后发生了什么?
- 3.触发多次setstate,那么render会执行几次?
- 4.setState是异步的原因
- 5.为什么建议传递给 setState的参数是一个callback而不是一个对象?
- 6.this.setState之后react做了哪些操作?
- 7.简述一下virtual DOM (虚拟dom)如何工作
- 8.为什么虚拟 dom 会提高性能?
- 9.react diff 原理
- 10.React 中 refs 的作用是什么?
- 11.React 中有哪些构建组件的方式?
- 12.事件处理函数的this指向问题
- 13.事件处理函数如何传递参数?
- 14.React 16 生命周期的变化
- 15.webpack的原理
- 16.babel 原理
- 17.虚拟DOM的理解
- 18.介绍Redux,主要解决什么问题?数据流程是怎么样的?多个组件使用相同状态如何进行管理?
- 19.中间件是怎么拿到store和action,然后怎么处理
- 20.React-Redux到react组件的连接过程
- 21.中间件是怎么拿到store和action,然后怎么处理
- 22.Redux中间件是什么东西,接受几个参数
- 23.redux请求中间件如何处理并发
- 24.Redux中异步的请求怎么处理
- 25.Redux状态管理器和变量挂载到window中有什么区别
- 26.如何配置React-Router
- 27.react-router怎么实现路由切换
- 28.路由的动态加载模块
- 29.前端怎么控制管理路由
- 30.多个组件之间如何拆分各自的state,每块小的组件有自己的状态,它们之间还有一些公共的状态需要维护,如何思考这块
- 31.React组件事件代理的原理
- 32.import { Button } from 'antd',打包的时候只打包button,分模块加载,是怎么做到的
- 33.React中Dom结构发生变化后内部经历了哪些变化?
- 34.setState是同步还是异步
- 35.React怎么做数据的检查和变化
- 36.哪些方法会触发react重新渲染
- 37.什么是高阶组件(HOC)?
- 38.diff算法
- 39.为什么使用hooks
- 40.什么是JSX?
- 41.为什么浏览器无法读取JSX?
- 42.理解“在React中,一切都是组件”这句话
- 43. 什么是 Props?
- 44.React中的状态是什么?它是如何使用的?
- 45.React中的合成事件是什么?
- 46.你能用高阶组件(HOC)做什么?
- 47.什么是纯组件?
- 48.你对受控组件和非受控组件了解多少?
- 49.Redux 有哪些优点
- 50.什么是React 路由
- 51.为什么React Router v4中使用 switch 关键字 ?
- 52.为什么React组件首字母必须大写?
- 53.React组件通信如何实现?
- 54.React的请求应该放在哪个生命周期中?
- 55.React与Vue的相似之处
- 56.react进行setState后触发了哪些钩子
- 57.react为什么数据是不可变的
- 58.react子组件产生变化会不会影响到父组件
- 59.redux的使用过程
- 60.react中的fragement
- 61.说一下用redux后,用户页面刷新后数据不存在了怎么办?怎么保存?怎么实现这个比如订单的增删改查?
- 62.常用的react生命周期有哪些周期函数?
- 63.react新增的生命周期函数?
- 64.component和purecomponent有什么区别
- 65.在哪个生命周期做优化?
- 66.react怎么从虚拟dom中拿出真实dom?(ref)
- 67.react router3是否用过,router4是否用过,3到4有什么改变
- 68.react是什么层面上的框架,数据流是单向流还是双向绑定,为什么
- 69.react-redux的实现原理
- 70.父组件里嵌套子组件是如何的渲染顺序
- 71.在生命周期哪个钩子做优化,如何优化的
- 72.虚拟DOM的优缺点
- 73.react性能优化
1.React 中 keys 的作用是什么?
Keys 是 React 用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识。
2.调用 setState 之后发生了什么?
- 在代码中调用 setState 函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程。
- 经过调和过程,React会以相对高效的方式根据新的状态构建React元素树并且着手重新渲染整个 UI 界面。
- 在 React 得到元素树之后,React 会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染。
- 在差异计算算法中,React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。
3.触发多次setstate,那么render会执行几次?
多次setState会合并为一次render,因为setState并不会立即改变state的值,而是将其放到一个任务队列里,最终将多个setState合并,一次性更新页面。
4.setState是异步的原因
- 当批量执行state的时候可以让DOM渲染的更快,也就是说多个setstate在执行的过程中还需要被合并
- 保持内部一致性 (即使state是同步更新,props也不是。)
- 启动并发更新 (可能有多个setstate 避免降低性能)
5.为什么建议传递给 setState的参数是一个callback而不是一个对象?
因为this.props 和this.state的更新可能是异步的,不能依赖它们的值去计算下一个state
6.this.setState之后react做了哪些操作?
- shouldComponentUpdate
- componentWillUpdate
- render
- componentDidUpdate
7.简述一下virtual DOM (虚拟dom)如何工作
- 当数据发生变化,比如setState时,会引起组件重新渲染,整个UI都会以virtual dom的形式重新渲染
- 然后收集差异也就是diff新的virtual dom和老的virtual dom的差异
- 最后把差异队列里的差异,比如增加节点、删除节点、移动节点更新到真实的DOM上
8.为什么虚拟 dom 会提高性能?
虚拟 dom 相当于在 js 和真实 dom 中间加了一个缓存,利用 dom diff 算法避免了没有必要的 dom 操作,从而提高性能。
9.react diff 原理
传统diff算法的时间复杂度为O(n^3), react却利用其特殊的diff算法做到了O(n3)到O(n)的飞跃性的提升
- 对应元素节点生成树形结构按照层级分解,只比较同级元素。
- 拥有相同类的两个组件将会生成相似的树形结构,拥有不同类的两个组件将会生成不同的树形结构。
- 对于同一层级的一组子节点,它们可以通过唯一 id 进行区分。
- 给列表结构的每个单元添加唯一的 key 属性,方便比较。
- React 只会匹配相同class的component(这里面的class指的是组件的名字)
- 合并操作,调用 component 的 setState 方法的时候, React 将其标记为 dirty.到每一个事件循环结束, React检查所有标记 dirty 的 component 重新绘制.
- 选择性子树渲染。开发人员可以重写 shouldComponentUpdate 提高 diff 的性能。
10.React 中 refs 的作用是什么?
Refs 是 React 提供给我们的安全访问DOM元素或者某个组件实例的句柄。
11.React 中有哪些构建组件的方式?
- 函数式组件 需要return出react元素
- class组件首字母大写
函数组件看似只是一个返回值是DOM结构的函数,其实它的背后是无状态组件的思想。
函数组件中,你无法使用State,也无法使用组件的生命周期方法,这就决定了函数组件都是展示性组件,接收Props,渲染DOM,而不关注其他逻辑
函数组件中没有this
函数组件更容易理解。当你看到一个函数组件时,你就知道它的功能只是接收属性,渲染页面,它不执行与UI无关的逻辑处理,它只是一个纯函数。而不用在意它返回的DOM结构有多复杂。
12.事件处理函数的this指向问题
13.事件处理函数如何传递参数?
- 可以使用 bind 传递参数
- 将事件处理函数交给箭头函数,然后在箭头函数里面调用我自己开始想要调用的那个方法,这时我已经是个普通函数了。
14.React 16 生命周期的变化
componentWillMount,componentWillReceiveProps, componentWillUpdate准备废除。理由:主要是16 版本 render 之前的生命周期可能会被多次执行。
static getDerivedStateFromProps和 getSnapshotBeforeUpdate新增,用于补充上述的生命周期。
15.webpack的原理
- 初始化参数:从配置文件和Shell语句中读取和合并参数;
- 开始编译:用上一步得到的初始化Compiler对象,加载所有配置的插件,执行对象的run的方法开始执行编译;
- 确定入口:根据配置中的ent ry找到所有的入口文件
- 编译模块:从入口文件出发,调用所有配置的Loader
对模块进行编译,再找出该模块依赖的模块,在递归本步骤直到所有入口依赖的文件都经过了本步骤的处理; - 完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系;
- 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk
转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会; - 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。
16.babel 原理
babel的转译过程分为三个阶段:parsing、transforming、generating,以ES6代码转译为ES5代码为例,babel转译的具体过程如下:
- ES6代码输入
- babylon 进行解析得到 AST
- plugin 用 babel-traverse 对 AST 树进行遍历转译,得到新的AST树
- 用 babel-generator 通过 AST 树生成 ES5 代码
17.虚拟DOM的理解
本质上是 JavaScript 对象
- 维护一个使用 JS 对象表示的 Virtual DOM,与真实 DOM 一一对应
- 对前后两个 Virtual DOM 做 diff ,生成变更(Mutation)
- 把变更应用于真实 DOM,生成最新的真实 DOM
18.介绍Redux,主要解决什么问题?数据流程是怎么样的?多个组件使用相同状态如何进行管理?
- 1.Redux是一个状态容器,解决了组件间的状态共享问题,实现了多组件通信,也是一种MVC机
- 2.Redux4个模块
- view - 组件状态改变时,dispatch一个action
- action:生成一个描述状态变化的action对象,并传递给store
- store:接收action对象并传递给reducer,驱动reducer执行状态更新任务,更新后刷新dom节点(即view中执行render)
- reducer:对action对象处理,更新组件状态,并将新的状态值返回store
- 3.Redux数据流程
- 创建一个store存储数据,定义改变store的action,里面是各种reducer的映射
- view层dispatch一个action,store接收到action修改状态,执行update方法,调用subscribe传进来的回调
- view层在componentDidMount中订阅状态更新,拿到更新后的store后setState、forceUpdate更新view
- 4.多组件使用相同状态。都放到同一个reducer里管理即可
19.中间件是怎么拿到store和action,然后怎么处理
- createStore时通过applyMiddleware函数把中间件和store关联起来的,store是在store初始化时传入中间件的。
- 中间件可以传入的方法参数转成数组,第一个中间件是第一次dispatch(action)时拿到action,后续中间件拿到的是经过前面的中间件处理后触发dispatch传入的action,即reduce过程
20.React-Redux到react组件的连接过程
- Provider为后代提供store:使用时在应用的最外层包一层,本质是上下文跨层级传递store
- connect为组件提供数据和变更方法:本质是高阶组件,连接React组件与Redux store,返回一个新的已经与Redux Store连接的组件类,实现多个组件使用相同状态。通过mapStateToProps和mapDispatchToProps给组件添加使用state和dispatch的方法。connect中通过setState触发组件render。
21.中间件是怎么拿到store和action,然后怎么处理
- createStore时通过applyMiddleware函数把中间件和store关联起来的,store是在store初始化时传入中间件的。
- 中间件可以传入的方法参数转成数组,第一个中间件是第一次dispatch(action)时拿到action,后续中间件拿到的是经过前面的中间件处理后触发dispatch传入的action,即reduce过程
22.Redux中间件是什么东西,接受几个参数
- redux中间件是一个函数,对dispatch方法增强,使dispatch不再接收纯对象的action,而是接受一个函数,把原来的dispatch当参数传进去。
- 接收参数是一系列的中间件函数,使用reduce实现compose,在action发出和执行reducer之间做这些操作。
23.redux请求中间件如何处理并发
redux-trunk中间件 - 传入dispatch的action可以定义成方法fun,fun可以拿到dispatch控制权,这样就可以自己控制何时出发reducer改变state
- 通过Promise.all实现并发
- 使用async、await配合Array.map() // forEach 循环是顺序执行不是并发?存疑
- 可以使用队列控制并发数量
redux-saga中间件 - generator + promise
24.Redux中异步的请求怎么处理
-
需要dispatch两次action,用户触发第一次dispatch时执行异步操作,异步操作有返回时触发真正的dispatch
-
使用redux-trunk,拿到dispatch控制权,就可以自己决定何时出发reducer改变state
25.Redux状态管理器和变量挂载到window中有什么区别
-
数据可控
-
数据响应
26.如何配置React-Router
1.npm install react-router-dom
2.router基本组件
- Router 路由器
- Link 连接
- Route 路由
- Switch 独占
- Redirect 重定向
27.react-router怎么实现路由切换
- Router组件使用Provider向下提供history对象,以及location的变更监听
- Route接收loaction(props || context),Router尝试其属性path与location进行匹配,匹配检测(children > component > render),内容渲染
- Link 跳转链接,生成一个a标签,禁用默认事件,js处理点击事件跳转(history.push) -> Link与直接使用a标签的区别是a页面会重新加载一下,Link只重新渲染Route组件部分
- Redirect to
- 从上下文中获取history this.context.router.history.push…
28.路由的动态加载模块
- 使用react-loadable包实现懒加载
- ()=>import(…)
29.前端怎么控制管理路由
实现一个PrivateRoute高阶组件做路由守卫
30.多个组件之间如何拆分各自的state,每块小的组件有自己的状态,它们之间还有一些公共的状态需要维护,如何思考这块
每块小组件自己的状态放到私有state中,公共的才用Redux管理
31.React组件事件代理的原理
- 事件委托:事件注册到document上
- 统一管理卸载
- e.stopPropagation阻止冒泡不可达到document层,解决:e.nativeEvent.stopImmediatePropagation()
- react源码通过一个合成事件映射表判断是否是合成事件
32.import { Button } from ‘antd’,打包的时候只打包button,分模块加载,是怎么做到的
通过 babel-plugin-import 配置处理。
{
"plugins": [
["import", {
"libraryName": "antd",
"libraryDirectory": "es",
"style": "css"
}]
]
}
相当于
import Button from 'antd/es/button';
import 'antd/es/button/style/css';
33.React中Dom结构发生变化后内部经历了哪些变化?
- setState引起状态变化
- React重新构建vnode树
- 和旧vnode树对比,得出变化部分Patches(diff算法)
- 将Patches更新到真实dom上
34.setState是同步还是异步
- 结论:原生事件、setTimeout中是同步,合成事件、生命周期中是异步
- 原因:React批量更新
- 源码中根据isBatchingUpdates(默认false,同步更新)判断立即更新,还是放到队列中延迟更新
- batchedUpdates方法会修改isBatchingUpdates为true,引起setState的异步更新
- React调用事件处理函数前会先调用batchedUpdates方法,所以由React处理的事件setState为异步。
35.React怎么做数据的检查和变化
- props:组件属性,专门用来连接父子组件间通信,父组件传输父类成员,子组件可以利用但不能编辑父类成员;
- state:专门负责保存和改变组件内部的状态;
36.哪些方法会触发react重新渲染
- 初始化
- 更新
- state发生改变
- props发送改变
- 强制更新
- this.forceUpdate
注意: <button onClick={() => this.forceUpdate()}>强制渲染
不可以写为<button onClick={this.forceUpdate}>强制渲染</button>
37.什么是高阶组件(HOC)?
- 高阶组件是一个函数(而不是组件),它接受一个组件作为参数,返回一个新的组件
- 高阶组件是重用组件逻辑的高级方法,是一种源于 React 的组件模式。 HOC 是自定义组件,在它之内包含另一个组件。它们可以接受子组件提供的任何动态,但不会修改或复制其输入组件中的任何行为。你可以认为 HOC 是“纯(Pure)”组件。
38.diff算法
- diff算法策略
- 不采用优化算法,把一个树转成另一个树的最小操作时间复杂度O(n3)
- 同级比较:Web中跨层移动节点几乎没有
- 不同类型(type、key)两个组件生成不同的树形结构
- 通过key暗示哪些元素相同
- diff过程 - 比对两个vnode时有3种操作:删除、替换、更新
- 删除:newVnode不存在
- 替换:vnode和newNode的type或key不同
- 更新:有相同类型的key但vnode和newVnode不同
- 当比较同类型元素时,React更新属性后执行render并将新老vdom尽心递归对比。
39.为什么使用hooks
- 只能在顶层调用Hooks? Hooks是使用数组或单链表串联起来,Hooks顺序修改会打乱执行结果
- hook之前的函数组件时无状态、无副作用,只作单纯的展示组件
- class组件的弊端,为什么要引入hook?
- 组件之间复用逻辑难,比如使用Context要引入Provider、Consumer,一层套一层
- 复杂组件变得难以理解:hook将组件中相互关联的部分拆成更小的函数
- 难以理解的class:比如js中的this问题、构建时的一些问题
- 引入hook之后函数组件发生了哪些变化?
- 函数组件可以存储和改变状态值:useState、useReducer
- 可以执行副作用:useEffect
- 复用状态逻辑: 自定义hook
40.什么是JSX?
JSX 是J avaScript XML 的简写。是 React 使用的一种文件,它利用 JavaScript 的表现力和类似 HTML 的模板语法。这使得 HTML 文件非常容易理解。此文件能使应用非常可靠,并能够提高其性能。下面是JSX的一个例子:
render(){
return(
<div>
<h1> Hello World from Edureka!!</h1>
</div>
);
}
41.为什么浏览器无法读取JSX?
浏览器只能处理 JavaScript 对象,而不能读取常规 JavaScript 对象中的 JSX。所以为了使浏览器能够读取 JSX,首先,需要用像 Babel 这样的 JSX 转换器将 JSX 文件转换为 JavaScript 对象,然后再将其传给浏览器。
42.理解“在React中,一切都是组件”这句话
组件是 React 应用 UI 的构建块。这些组件将整个 UI 分成小的独立并可重用的部分。每个组件彼此独立,而不会影响 UI 的其余部分。
43. 什么是 Props?
Props 是 React 中属性的简写。它们是只读组件,必须保持纯,即不可变。它们总是在整个应用中从父组件传递到子组件。子组件永远不能将 prop 送回父组件。这有助于维护单向数据流,通常用于呈现动态生成的数据。
44.React中的状态是什么?它是如何使用的?
状态是 React 组件的核心,是数据的来源,必须尽可能简单。基本上状态是确定组件呈现和行为的对象。与props 不同,它们是可变的,并创建动态和交互式组件。可以通过 this.state() 访问它们。
45.React中的合成事件是什么?
合成事件是围绕浏览器原生事件充当跨浏览器包装器的对象。它们将不同浏览器的行为合并为一个 API。这样做是为了确保事件在不同浏览器中显示一致的属性。
46.你能用高阶组件(HOC)做什么?
- 代码重用,逻辑和引导抽象
- 渲染劫持(权限控制)
- 状态抽象和控制
- Props 控制
- 表单校验
47.什么是纯组件?
纯(Pure) 组件是可以编写的最简单、最快的组件。它们可以替换任何只有 render() 的组件。这些组件增强了代码的简单性和应用的性能。
48.你对受控组件和非受控组件了解多少?
- 受控组件
- 没有维持自己的状态
- 数据由父组件控制
- 通过 props 获取当前值,然后通过回调通知更改
- 非受控组件
- 保持着自己的状态
- 数据由 DOM 控制
- Refs 用于获取其当前值
49.Redux 有哪些优点
- 结果的可预测性 - 由于总是存在一个真实来源,即 store ,因此不存在如何将当前状态与动作和应用的其他部分同步的问题。
- 可维护性 - 代码变得更容易维护,具有可预测的结果和严格的结构。
- 服务器端渲染 - 你只需将服务器上创建的 store 传到客户端即可。这对初始渲染非常有用,并且可以优化应用性能,从而提供更好的用户体验。
- 开发人员工具 - 从操作到状态更改,开发人员可以实时跟踪应用中发生的所有事情。
- 社区和生态系统 - Redux 背后有一个巨大的社区,这使得它更加迷人。一个由才华横溢的人组成的大型社区为库的改进做出了贡献,并开发了各种应用。
- 易于测试 - Redux 的代码主要是小巧、纯粹和独立的功能。这使代码可测试且独立。
- 组织 - Redux 准确地说明了代码的组织方式,这使得代码在团队使用时更加一致和简单。
50.什么是React 路由
React 路由是一个构建在 React 之上的强大的路由库,它有助于向应用程序添加新的屏幕和流。这使 URL 与网页上显示的数据保持同步。它负责维护标准化的结构和行为,并用于开发单页 Web 应用。 React 路由有一个简单的API
51.为什么React Router v4中使用 switch 关键字 ?
虽然
52.为什么React组件首字母必须大写?
babel在编译时会判断 JSX中组件的首字母,当首字母为小写时,其被认定为原生 DOM标签, createElement的第一个变量被编译为字符串;当首字母为大写时,其被认定为自定义组件, createElement的第一个变量被编译为对象;
53.React组件通信如何实现?
- 父组件向子组件通讯: 父组件可以向子组件通过传 props 的方式,向子组件进行通讯
- 子组件向父组件通讯: props+回调的方式,父组件向子组件传递props进行通讯,此props为作用域为父组件自身的函数,子组件调用该函数,将子组件想要传递的信息,作为参数,传递到父组件的作用域中
- 兄弟组件通信: 找到这两个兄弟节点共同的父节点,结合上面两种方式由父节点转发信息进行通信
- 跨层级通信:Context( redux )设计目的是为了共享那些对于一个组件树而言是“全局”的数据,例如当前认证的用户、主题或首选语言,对于跨越多层的全局数据通过Context通信再适合不过
54.React的请求应该放在哪个生命周期中?
在componentWillMount请求会有一系列潜在的问题,首先,在服务器渲染时,如果在componentWillMount 里获取数据,fetch data会执行两次,一次在服务端一次在客户端,这造成了多余的请求,其次,在React 16进行React Fiber重写后,componentWillMount可能在一次渲染中多次调用.
目前官方推荐的异步请求是在componentDidmount中进行.
55.React与Vue的相似之处
- 都使用 Virtual DOM
- 组件化。
- 将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库。
56.react进行setState后触发了哪些钩子
-
setState的改变会触发4个生命周期钩子
- shouldComponentUpdate
- componentWillUpdate
- render
- componentDidUpdate
-
props的改变会触发5个生命周期钩子
- componentWillReveiceProps
- shouldComponentUpdate
- componentWillUpdate
- render
- componentDidUpdate
57.react为什么数据是不可变的
因为,从React渲染组件性能考虑,使用旧数据创建新数据时,要保证旧数据同时可用且不变。
如果是简单的赋值给一个新的变量,新的对象和旧的对象只是名称不同,实际上占用了同样的内存地址仅仅名称不同
这对react响应重新渲染造成了性能影响,或不能及时更新dom。
58.react子组件产生变化会不会影响到父组件
只要父组件的render了,那么默认情况下就会触发子组件的render过程,子组件的render过程又会触发它的子组件的render过程,一直到React元素(即jsx中的
59.redux的使用过程
Store的角色是整个应用的数据存储中心,集中大部分页面需要的状态数据;
ActionCreators ,view 层与data层的介质;
Reduce ,接收action并更新Store。
所以流程是 用户通过界面组件 触发ActionCreator,携带Store中的旧State与Action 流向Reducer,Reducer返回新的state,并更新界面。
60.react中的fragement
代替div作为外层,可做不可见的包裹元素。
61.说一下用redux后,用户页面刷新后数据不存在了怎么办?怎么保存?怎么实现这个比如订单的增删改查?
一般我们可以使用sessionStorage或者localStorage来达到数据存储的要求
62.常用的react生命周期有哪些周期函数?
- 初始阶段:
- constructor
- componentWillMount
- render
- componentDidMount
- 更新阶段:
- componentWillReceiveProps
- shouldComponentUpdate
- componentWillUpdate
- render
- componentDidUpdate
- 卸载阶段
- componentWillUnmount
- 错误处理阶段
- componentDidCatch
63.react新增的生命周期函数?
- Mounting (挂载阶段)
static getDerivedStateFromProps(nextProps, prevState)
这个生命周期函数只要页面update就会被触发
这个生命周期的意思就是根据从props中获取state,实际上就是将传入的props映射到state上面
返回值是一个对象,这个对象的作用和setState一样用于更新state,返回值为null时,不更新state状态。提供给我们一个在渲染之前操作state的机会(慎用!)
该方法在每次render(渲染)被调用之前调用,意味着即使你的props没有任何变化,但因为state发生了变化,导致组件重新的render,这个生命周期函数依然会被调用。(父组件渲染导致了组件的重新渲染,即使子组件接收的属性没有更新,这一方法也会被调用)。
因为该方法为静态方法,所以内部不能使用this关键字。也就是这个函数不能通过this访问到class的属性,也并不推荐直接访问属性。而是应该通过参数提供的nextProps以及prevState来进行判断,根据新传入的props来映射到state。 - Updating (更新阶段)
触发时间: update发生的时候,在render之后可以读取但无法使用DOM的时候。它使您的组件可以在可能更改之前从DOM捕获一些信息(在虚拟DOM转化为真实DOM的前一刻自动调用。这个时间点getSnapshotBeforeUpdate可以用于读取即将被改变的数据);
这一生命周期返回的任何值将会 作为componentDidUpdate的第三个参数。配合componentDidUpdate, 可以覆盖componentWillUpdate的所有用法 - 错误边界
static getDerivedStateFromError(error)
在后代组件抛出错误后调用getDerivedStateFromError生命周期。它接收作为错误信息作为参数,并应该返回一个值去更新状态。
被调用是在 “渲染” 阶段,所以不允许副作用。
64.component和purecomponent有什么区别
PureComponent自带通过props和state的浅对比来实现 shouldComponentUpate(),而Component没有。
65.在哪个生命周期做优化?
shouldComonentUpdate 可以避免无畏组件render函数的运行。
66.react怎么从虚拟dom中拿出真实dom?(ref)
给虚拟dom添加ref属性
然后可以在函数中通过
ReactDOM.findDOMNode(this.refs.tip)来获取真实的dom节点
67.react router3是否用过,router4是否用过,3到4有什么改变
Router3用的是传统统一定义路由
Router4 用的一切皆组件 路由是由路由组件构成
68.react是什么层面上的框架,数据流是单向流还是双向绑定,为什么
视图层的框架(MVC),单项数据流,单向数据流组件props是父级往下传递,你不能向上去修改父组件的数据,并且也不能在自身组件中修改props的值
69.react-redux的实现原理
Provider:从最外部封装了整个应用,并向connect模块传递store。
Connect:
- 包装原组件,将state和action通过props的方式传入到原组件内部。
- 监听store tree变化,使其包装的原组件可以响应state变化
70.父组件里嵌套子组件是如何的渲染顺序
/* 父组件 */
import React, { Component } from 'react';
import Header from './components/Header'
import Footer from './components/Footer'
import BodyIndex from './components/BodyIndex'
class App extends Component {
componentWillMount() {
console.log('App-页面即将加载')
}
componentDidMount() {
console.log('App-页面加载完成')
}
render() {
return (
<div className="App">
<Header />
<BodyIndex />
<Footer />
</div>
);
}
}
/* console.log()内容和顺序如下 */
App-页面即将加载
Header-页面即将加载
body-页面即将加载
Footer-页面即将加载
Header-页面加载完成
body-页面加载完成
Footer-页面加载完成
App-页面加载完成
71.在生命周期哪个钩子做优化,如何优化的
shouldComponentUpdate函数是重渲染时render()函数调用前被调用的函数,它接受两个参数:nextProps和nextState,分别表示下一个props和下一个state的值。并且,当函数返回false时候,阻止接下来的render()函数的调用,阻止组件重渲染,而返回true时,组件照常重渲染。
72.虚拟DOM的优缺点
优点
- 保证性能下限。 操作真实的dom结构是一件非常昂贵的事情,虚拟Dom利用js对象来模拟真实的dom,从而降低了逻辑层面对dom结构操作的成本
- 无需操作真实的dom。 通过双向数据绑定,当数据发生改变的时候,dom结构中的节点自动更新,无需我们手动处理
- 可移植性高,跨平台性好。 无论是vue、react还是weex等,我们都能看到虚拟dom的身影,通过各自的渲染进制进行将Dom结构渲染出来
缺点
- 无法进行极致优化: 虽然虚拟 DOM+合理的优化,足以应对绝大部分应用的性能需求,但在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化。
73.react性能优化
- 作用域的修改放在constructor中
constructor (props) {
super(props)
// 当组件的state或者props发生改变的的时候,render函数就是重新执行
this.state = {
inputValue: '',
list: []
}
// 将this指向放在constructor中执行,在复杂的组件开发中节约性能
this.handleInputChange = this.handleInputChange.bind(this)
this.handleBtnChange = this.handleBtnChange.bind(this)
this.handleItemDelete = this.handleItemDelete.bind(this)
}
- setState异步函数
- setState内置了性能优化的机制,它是一个异步函数,可以把多次的数据改变结合成一次来做,这样的话降低虚拟DOM的对比频率,来提高性能
- 虚拟DOM(key)
- React底层运用了虚拟DOM,他还有同层比对,key值的调用,来提升虚拟DOM的比对速度,从而提升React的性能
- 复用的组件
- 组件传递参数只传用到的(props)
- shouldComponentUpdate生命周期函数