react
我从2015在外企因工作需要使用了react native,然后就踏上了前端的不归路,这几年工作中都有使用react 开发项目,虽然我面试别人很少问这方面的问题,但是自己去被别人面还是经常会有人考我,特别是阿里系的岗位。
组件的state和props有何不同?
- props 由父组件传递给子组件,就子组件而言,props 是不可变的;
- State 是一种数据结构,用于组件挂载时所需数据的默认值。
调用 setState 发生了什么?
- 将传入的参数对象与组件当前的状态合并;
- 触发调和过程,根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面;
- 自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染,按需更新,而不是全部重新渲染。
React 中 keys 的作用是什么?
- key 是 React 用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识,我们需要保证某个元素的 key 在其同级元素中具有唯一性。
- 在 Diff 算法中 React 会借助元素的 Key 值来判断该元素是新近创建的还是被移动而来的元素,从而减少不必要的元素重渲染。
- 此外,React 还需要借助 Key 值来判断元素与本地状态的关联关系,因此我们绝不可忽视转换函数中 Key 的重要性。
react 生命周期函数有哪些?
- 初始化阶段:
- getDefaultProps:获取实例的默认属性
- getInitialState:获取每个实例的初始化状态
- componentWillMount:组件即将被装载、渲染到页面上
- render:组件在这里生成虚拟的 DOM 节点
- componentDidMount:组件真正在被装载之后
- 运行阶段:
- componentWillReceiveProps:组件将要接收到属性的时候调用
- shouldComponentUpdate:组件接受到新属性或者新状态的时候
- componentWillUpdate:组件即将更新不能修改属性和状态
- render:组件重新描绘
- componentDidUpdate:组件已经更新
- 销毁阶段:
- componentWillUnmount:组件即将销毁
react怎么从虚拟dom中拿出真实dom?
refs 是 React 提供给我们的安全访问 DOM 元素或者某个组件实例的句柄, 我们可以通过this.$refs 获取对应我们标记的dom元素。
React如何性能优化?
- 减少对真实DOM的操作;
- 能用const声明的就用const;
- 给遍历的DOM上加上唯一的key;
- 重写shouldComponentUpdate来避免不必要的dom操作;
- DOM里少用箭头函数;
- bind 函数尽量写在constructor,避免每次render重新bind;
- 如果是用webpack搭建环境的话,通过适当拆包和压缩来优化。
react diff 原理?
它的作用是计算出Virtual DOM中真正变化的部分,并只针对该部分进行原生DOM操作,而非重新渲染整个页面。
将Virtual DOM树转换成actual DOM树的最少操作的过程 称为 调和,diff算法是调和的具体实现。
- React 通过分层求异的策略,对 tree diff 进行算法优化;
- React 通过相同类生成相似树形结构,不同类生成不同树形结构的策略,对 component diff 进行算法优化;
- React 通过设置唯一 key的策略,对 element diff 进行算法优化;
建议:
- 在开发组件时,保持稳定的 DOM 结构会有助于性能的提升;
- 在开发过程中,尽量减少类似将最后一个节点移动到列表首部的操作,当节点数量过大或更新操作过于频繁时,在一定程度上会影响 React 的渲染性能。
react虚拟DOM实现原理?
- 用 js对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档中;
- 当状态变更的时候,重新构造一棵新的对象树,对比新旧虚拟DOM树,记录两棵树差异;
- 把 2 所记录的差异应用到步骤 1 所构建的真正的 DOM 树上,视图就更新了。
Redux的实现流程
- 用户页面行为触发一个Action,Store 自动调用 Reducer,并且传入两个参数:当前 State 和收到的 Action;
- Reducer 会返回新的 State,view根据state触发重新渲染。
react-redux的实现原理
Redux作为一个通用模块,主要还是用来处理应用中state的变更,通过react-redux做连接,可以在React+Redux的项目中将两者结合的更好。
react-redux是一个轻量级的封装库,它主要通过两个核心方法实现:
- Provider:从最外部封装了整个应用,并向connect模块传递store。
- Connect:
- 包装原组件,将state和action通过props的方式传入到原组件内部。
- 监听store tree变化,使其包装的原组件可以响应state变化
react如何实现复用?
封装与复用是一个经典的话题,低效的工作方式是我们加班加点最主要的原因之一,封装与复用帮助我们把能改变的做好。
render-props 和 HOC 作为 react 中的代码复用方式,都得到了广泛的使用,多数情况下, 两者是可以互换的,主要区别在于:
- render props 是细粒度的代码复用,如某个 render 函数里的某个组件依赖一些属性和方法时;
- hoc 是粗粒度的代码复用,可以扭转整个组件的行为,外部调用和内部使用,都不会造成影响。
react hooks 是react 16.8 引入的特性,允许在不写class的情况下操作state 和react的其他特性。
通过自定义hook把公共的逻辑提取出来,让逻辑在多个组件之间共享。
Hooks 的出现本质是把这种面向生命周期编程变成了面向业务逻辑编程,你不用再去关心本不该关心的生命周期。
HOC 和 Render Props 还是有存在的必要,一方面是支持 React Class,另一方面,它们不光适用于纯逻辑封装,很多时候也适合逻辑 + 组件的封装场景,虽然此时使用 Hooks 也可以,但是会显得啰嗦点。
小结
国内有关react 的教程和源码分析相对没有vue多,而且目前国内使用vue的新项目更多,我这几年面试一般都会跟面试官说我对vue更熟悉,所以问react的问题就比较少。