REACT面试题总结

react生命周期有哪些

组件载入阶段:

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

运行中状态:

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

shouldComponentUpdate:组件接受到新属性或者新状态的时候(返回 false,接收数据后不更新,阻止 render ,后面的函数不会继续执行)

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

componentWillUpdate:组件即将更新不能修改属性和状态
componentDidUpdate:组件已经更新

销毁阶段:

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

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

https://www.jianshu.com/p/b331d0e4b398

为什么不能用数组下标来作为react组件中的key?

react 使用diff算法,使用key来做同级比对。如果使用数组下标作为key,有以下情况:
在数组头部或中部插入或删除元素: 所有key对应的节点的值发生更改,进行重新渲染。造成性能损耗
而如果使用数组中唯一值来作为key:不管是在何处插入或删除节点,其他key对应的节点的值未发生更改,只需插入或删除操作的数组节点。

react的diff算法是怎么完成的

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

https://www.jianshu.com/p/3ba0822018cf

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可以传字符串。

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

React中的props和state的用法

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

react组件之间如何通信

父子:父传子:props; 子传父:子调用父组件中的函数并传参;
兄弟:利用redux实现。

react的setState的原理及用法

原理:

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

Batch Update:https://zhuanlan.zhihu.com/p/28532725

使用:

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

1
2
3
this.setState({
isLoading:false
})

2.还可以接收一个函数

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

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

1
2
3
this.setState({count:2},()=>{
isLoading:this.state.count===2 ? true : false
})

setState为什么是异步的

https://segmentfault.com/a/1190000013040438

  1. 保证内部的一致性
    因为props是要等到父组件渲染过后才能拿到,也就是不能同步更新,state出于统一性设成异步更新。
  2. 性能优化
    举例说你正在一个聊天窗口输入,如果来了一条新消息又要render,那就会阻塞你的当前操作,导致延迟什么的。
  3. 支持state在幕后渲染
    异步可以使state在幕后更新,而不影响你当前旧的页面的交互,提升用户体验。
    详情可以点击上面的参考链接,写的很详细的。

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

https://segmentfault.com/a/1190000014131698

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与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变化

坚持原创技术分享,您的支持将鼓励我继续创作!