React面试题(超详细,附答案)
生命周期
-
组件将要挂载时触发的函数:
componentWillMount
-
组件挂载完成时触发的函数:
componentDidMount
-
是否要更新数据时触发的函数:
shouldComponentUpdate
-
将要更新数据时触发的函数:
componentWillUpdate
-
数据更新完成时触发的函数:
componentDidUpdate
-
组件将要销毁时触发的函数:
componentWillUnmount
-
父组件中改变了props传值时触发的函数:
componentWillReceiveProps
shouldComponentUpdate
shouldComponentUpdate
允许我们手动地判断是否要进行组件更新,根据组件的应用场景设置函数的合理返回值能够帮我们避免不必要的更新
React 中 keys 的作用是什么?
Keys
是React
用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识
-
在开发过程中,我们需要保证某个元素的
key
在其同级元素中具有唯一性。在React Diff
算法中React
会借助元素的Key
值来判断该元素是新近创建的还是被移动而来的元素,从而减少不必要的元素重渲染。此外,React 还需要借助Key
值来判断元素与本地状态的关联关系,因此我们绝不可忽视转换函数中Key
的重要性
(组件的)状态(state)和属性(props)之间有何不同?
-
State 是一种数据结构,用于组件挂载时所需数据的默认值。State 可能会随着时间的推移而发生突变,但多数时候是作为用户事件行为的结果
-
Props(properties 的简写)则是组件的配置。props 由父组件传递给子组件,并且就子组件而言,props 是不可变的(immutable)。组件不能改变自身的 props,但是可以把其子组件的 props 放在一起(统一管理)。Props 也不仅仅是数据–回调函数也可以通过 props 传递。
何为受控组件(controlled component)?
在 HTML 中,类似
<input/>
,<select>
和<textarea>
这样的表单元素会维护自身的状态,并基于用户的输入来更新。当用户提交表单时,前面提到的元素的值将随表单一起被发送。但在 React 中会有些不同,包含表单元素的组件将会在 state 中追踪输入的值,并且每次调用回调函数时,如onChange
会更新 state,重新渲染组件。一个输入表单元素,它的值通过 React 的这种方式来控制,这样的元素就被称为”受控元素”。
展示组件(Presentational component)(也叫 UI
组件)和容器组件(Container component)(负责应用逻辑处理)之间有何不同
-
展示组件(
UI
组件)-
负责展示
UI
,也就是组件如何渲染,具有很强的内聚性 -
只关心得到数据后如何渲染
-
-
容器组件(逻辑组件)
-
负责应用逻辑处理,发送网络请求,处理返回数据,将处理过的数据传递给展示组件
-
也提供修改数据源的方法,通过展示组件的props传递给展示组件
-
当展示组件的状态变更引起源数据变化时,展示组件通过调用容器组件提供的方法同步这些变化
-
react-router的原理
-
BrowserRouter
或HashRouter
用来渲染Router所代表的组件-
BrowserRouter
–浏览器路由(属于后端路由) 会有一个#,通过这个# HTML 5 History进行前端跳转他的感觉像锚点 -
HasRouter
–前端has路由(属于前端路由)很简洁没有#,但是需要 server 端支持
-
-
Route
用来匹配组件路径并且筛选需要渲染的组件 -
Switch
用来筛选需要渲染的唯一组件 -
Link
直接渲染某个页面组件 -
Redirect
类似于Link,在没有Route匹配成功时触发
何为高阶组件(HOC)?
高阶组件 其实就是一个函数而已,只不过参数是一个组件而已,返回了一个新的组件
复用组件的业务逻辑
react-redux
connect
其实就是一个高阶组件HOC 是纯函数,没有副作用 ——纯函数:输入确定,输出就一定确定
了解 redux
么,说一下 redux
-
redux
是一个应用数据流框架,主要是解决了组件间状态共享的问题,原理是集中式管理 -
主要有三个核心方法,
action
,store
,reducer
-
工作流程是 view 调用 store 的 dispatch 接收 action 传入 store,reducer 进行 state 操作,view 通过 store 提供的
getState
获取最新的数据 -
新增 state,对状态的管理更加明确,通过 redux,流程更加规范了,减少手动编码量,提高了编码效率,同时缺点时当数据更新时有时候组件不需要,但是也要重新绘制,有些影响效率。一般情况下,我们在构建多交互,多数据流的复杂项目应用时才会使用它们
redux
中间件的理解,以及用过哪些中间件
-
redux-thunk
:处理异步操作 -
redux-saga
:处理异步操作 -
redux-promise
:处理异步操作,actionCreator
的返回值是promise
Redux
遵循的三个原则是什么?
-
单一事实来源:整个应用程序的状态存储在单个存储中的对象/状态树中
-
状态是只读的:更改状态的惟一方法是触发一个动作
-
使用纯函数来修改state:为了描述 action 如何改变 state tree ,你需要编写reducers
React
, redux
可以运行在服务端吗?有什么优势
-
利于
SEO
-
提高首屏渲染速度
-
同构直出,使用同一份
JS
代码实现,便于开发和维护
react性能优化方案
-
重写
shouldComponentUpdate
来避免不必要的dom
操作 -
使用
production
版本的react.js
-
使用
key
来帮助React
识别列表中所有子组件的最小变化
说说你用react有什么坑点?
-
JSX
做表达式判断时候,需要强转为boolean类型
-
尽量不要在
componentWillReviceProps
里使用setState
,如果一定要使用,那么需要判断结束条件,不然会出现无限重渲染,导致页面崩溃 -
遍历子节点的时候,不要用 index 作为组件的 key 进行传入
react 的虚拟 dom
是怎么实现的?
首先说说为什么要使用
Virturl DOM
,因为操作真实DOM
的耗费的性能代价太高,所以react
内部使用js
实现了一套dom
结构,在每次操作在和真实dom
之前,使用实现好的diff
算法,对虚拟dom
进行比较,递归找出有变化的dom
节点,然后对其进行更新操作。为了实现虚拟DOM
,我们需要把每一种节点类型抽象成对象,每一种节点类型有自己的属性,也就是prop,每次进行diff
的时候,react
会先比较该节点类型,假如节点类型不一样,那么react
会直接删除该节点,然后直接创建新的节点插入到其中,假如节点类型一样,那么会比较prop
是否有更新,假如有prop
不一样,那么react
会判定该节点有更新,那么重渲染该节点,然后在对其子节点进行比较,一层一层往下,直到没有子节点
react
diff
原理
-
把树形结构按照层级分解,只比较同级元素
-
给列表结构的每个单元添加唯一的 key 属性,方便比较
-
React 只会匹配相同 class 的 component(这里面的 class 指的是组件的名字)
-
合并操作,调用 component 的
setState
方法的时候, React 将其标记为 dirty.到每一个事件循环结束, React 检查所有标记 dirty 的 component 重新绘制 -
选择性子树渲染。开发人员可以重写
shouldComponentUpdate
提高diff
的性能
react 的渲染过程中,兄弟节点之间是怎么处理的?也就是key值不一样的时候
我们必须给每一个元素添加
key
属性,大概的作用就是给每一个元素添加一个身份标识,方便react进行识别,在重渲染过程中,如果key一样,若组件属性有所变化,则react
只更新组件对应的属性;没有变化则不更新,如果key不一样,则react先销毁该组件,然后重新创建该组件
react组件之间如何通信?
父子:父传子:props; 子传父:子调用父组件中的函数并传参; 兄弟:利用
redux
实现。 所有关系都通用的方法:利用PubSub.js
订阅
setState
为什么是异步的
-
保证内部的一致性 (因为props是要等到父组件渲染过后才能拿到,也就是不能同步更新,state出于统一性设成异步更新)
-
性能优化 (举例说你正在一个聊天窗口输入,如果来了一条新消息又要render,那就会阻塞你的当前操作,导致延迟什么的)
-
支持state在幕后渲染(异步可以使state在幕后更新,而不影响你当前旧的页面的交互,提升用户体验)
react的优势以及特点
-
优势
-
实现对虚拟DOM的操作,使得它速度快,提高了Web性能
-
组件化,模块化。react里每一个模块都是一个组件,组件化开发,可维护性高
-
单向数据流,比较有序,有便于管理,它随着React视图库的开发而被
Facebook
概念化 -
跨浏览器兼容:虚拟DOM帮助我们解决了跨浏览器问题,它为我们提供了标准化的
API
,甚至在IE8
中都是没问题的
-
-
不足
-
react中只是
MVC
模式的View部分,要依赖引入很多其他模块开发 -
当父组件进行重新渲染操作时,即使子组件的props或state没有做出任何改变,也会同样进行重新渲染
-
-
特点
-
声明式设计:React采用声明范式,可以轻松描述应用
-
高效:React通过对DOM的模拟,最大限度地减少与DOM的交互
-
灵活:React可以与已知的库或框架很好地配合
-