美团前端经典 react 面试题整理
react 强制刷新
component.forceUpdate() 一个不常用的生命周期方法, 它的作用就是强制刷新
官网解释如下
默认情况下,当组件的 state 或 props 发生变化时,组件将重新渲染。如果 render() 方法依赖于其他数据,则可以调用 forceUpdate() 强制让组件重新渲染。
调用 forceUpdate() 将致使组件调用 render() 方法,此操作会跳过该组件的 shouldComponentUpdate()。但其子组件会触发正常的生命周期方法,包括 shouldComponentUpdate() 方法。如果标记发生变化,React 仍将只更新 DOM。
通常你应该避免使用 forceUpdate(),尽量在 render() 中使用 this.props 和 this.state。
shouldComponentUpdate 在初始化 和 forceUpdate 不会执行
React 父组件如何调用子组件中的方法?
如果是在方法组件中调用子组件(>= react@16.8),可以使用 useRef 和
useImperativeHandle
:
如果是在类组件中调用子组件(
>= react@16.4
),可以使用 createRef:
React 中 Diff 算法的原理是什么?
原理如下。(1)节点之间的比较。节点包括两种类型:一种是 React 组件,另一种是 HTML 的 DOM。如果节点类型不同,按以下方式比较。如果 HTML DOM 不同,直接使用新的替换旧的。如果组件类型不同,也直接使用新的替换旧的。如果 HTML DOM 类型相同,按以下方式比较。在 React 里样式并不是一个纯粹的字符串,而是一个对象,这样在样式发生改变时,只需要改变替换变化以后的样式。修改完当前节点之后,递归处理该节点的子节点。如果组件类型相同,按以下方式比较。如果组件类型相同,使用 React 机制处理。一般使用新的 props 替换旧的 props,并在之后调用组件的 componentWillReceiveProps 方法,之前组件的 render 方法会被调用。节点的比较机制开始递归作用于它的子节点。(2)两个列表之间的比较。一个节点列表中的一个节点发生改变, React 无法很妤地处理这个问题。循环新旧两个列表,并找出不同,这是 React 唯一的处理方法。但是,有一个办法可以把这个算法的复杂度降低。那就是在生成一个节点列表时给每个节点上添加一个 key。这个 key 只需要在这一个节点列表中唯一,不需要全局唯一。(3)取舍需要注意的是,上面的启发式算法基于两点假设。类型相近的节点总是生成同样的树,而类型不同的节点也总是生成不同的树可以为多次 render 都表现稳定的节点设置 key。上面的节点之间的比较算法基本上就是基于这两个假设而实现的。要提高 React 应用的效率,需要按照这两点假设来开发。
传入 setState 函数的第二个参数的作用是什么?
该函数会在
setState
函数调用完成并且组件开始重渲染的时候被调用,我们可以用该函数来监听渲染是否完成:
redux 有什么缺点
一个组件所需要的数据,必须由父组件传过来,而不能像
flux
中直接从store
取。当一个组件相关数据更新时,即使父组件不需要用到这个组件,父组件还是会重新
render
,可能会有效率影响,或者需要写复杂的shouldComponentUpdate
进行判断。
redux 中间件
中间件提供第三方插件的模式,自定义拦截
action
->reducer
的过程。变为action
->middlewares
->reducer
。这种机制可以让我们改变数据流,实现如异步action
,action
过滤,日志输出,异常报告等功能
redux-logger
:提供日志输出redux-thunk
:处理异步操作redux-promise
:处理异步操作,actionCreator
的返回值是promise
参考 前端进阶面试题详细解答
组件更新有几种方法
this.setState() 修改状态的时候 会更新组件
this.forceUpdate() 强制更新
组件件 render 之后,子组件使用到父组件中状态,导致子组件的 props 属性发生改变的时候 也会触发子组件的更新
什么是 React 的 refs?为什么它们很重要
refs 允许你直接访问 DOM 元素或组件实例。为了使用它们,可以向组件添加个 ref 属性。如果该属性的值是一个回调函数,它将接受底层的 DOM 元素或组件的已挂载实例作为其第一个参数。可以在组件中存储它。
如果该属性值是一个字符串, React 将会在组件实例化对象的 refs 属性中,存储一个同名属性,该属性是对这个 DOM 元素的引用。可以通过原生的 DOM API 操作它。
React 中 refs 的作用是什么
Refs
是React
提供给我们的安全访问DOM
元素或者某个组件实例的句柄可以为元素添加
ref
属性然后在回调函数中接受该元素在DOM
树中的句柄,该值会作为回调函数的第一个参数返回
hooks 为什么不能放在条件判断里
以 setState 为例,在 react 内部,每个组件(Fiber)的 hooks 都是以链表的形式存在 memoizeState 属性中
update 阶段,每次调用 setState,链表就会执行 next 向后移动一步。如果将 setState 写在条件判断中,假设条件判断不成立,没有执行里面的 setState 方法,会导致接下来所有的 setState 的取值出现偏移,从而导致异常发生。
useEffect(fn, []) 和 componentDidMount 有什么差异
useEffect
会捕获props
和 state。所以即便在回调函数里,你拿到的还是初始的 props 和 state。如果想得到“最新”的值,可以使用 ref。
生命周期调用方法的顺序是什么?
React 生命周期分为三大周期,11 个阶段,生命周期方法调用顺序分别如下。(1)在创建期的五大阶段,调用方法的顺序如下。
getDetaultProps:定义默认属性数据。
getInitialState:初始化默认状态数据。
component WillMount:组件即将被构建。
render:渲染组件。
componentDidMount:组件构建完成
(2)在存在期的五大阶段,调用方法的顺序如下。
componentWillReceiveProps:组件即将接收新的属性数据。
shouldComponentUpdate:判断组件是否应该更新。
componnent WillUpdate:组件即将更新。
render:渲染组件。
componentDidUpdate:组件更新完成。
(3)在销毁期的一个阶段,调用方法 componentWillUnmount,表示组件即将被销毀。
react 性能优化方案
重写
shouldComponentUpdate
来避免不必要的 dom 操作使用
production
版本的react.js
使用
key
来帮助React
识别列表中所有子组件的最小变化
这三个点(...)在 React 干嘛用的?
...
在 React(使用 JSX)代码中做什么?它叫什么?
这个叫扩展操作符号或者展开操作符,例如,如果this.props
包含a:1
和b:2
,则
等价于下面内容:
扩展符号不仅适用于该用例,而且对于创建具有现有对象的大多数(或全部)属性的新对象非常方便,在更新state
咱们就经常这么做:
diff 算法?
把树形结构按照层级分解,只比较同级元素。
给列表结构的每个单元添加唯一的
key
属性,方便比较。React
只会匹配相同class
的component
(这里面的class
指的是组件的名字)合并操作,调用
component
的setState
方法的时候,React
将其标记为 -dirty
.到每一个事件循环结束,React
检查所有标记dirty
的component
重新绘制.选择性子树渲染。开发人员可以重写
shouldComponentUpdate
提高diff
的性能
在构造函数调用 super
并将 props
作为参数传入的作用是啥?
在调用 super()
方法之前,子类构造函数无法使用this
引用,ES6 子类也是如此。将 props
参数传递给 super()
调用的主要原因是在子构造函数中能够通过this.props
来获取传入的 props
。 传递 props
没传递 props
上面示例揭示了一点。props
的行为只有在构造函数中是不同的,在构造函数之外也是一样的。
这段代码有什么问题?
render ( < App intro=" 前端技术专业学习平台">,ickt )在页面中正常输出“有课前端网-前端技术专业学习平台”。但是这种写法很少使用,并不是常用的写法。React 允许对 setState 方法传递一个函数,它接收到先前的状态和属性数据并返回一个需要修改的状态对象,正如我们在上面所做的那样。它不但没有问题,而且如果根据以前的状态( state)以及属性来修改当前状态,推荐使用这种写法。
React- Router 有几种形式?
有以下几种形式。HashRouter,通过散列实现,路由要带 #。BrowerRouter,利用 HTML5 中 history API 实现,需要服务器端支持,兼容性不是很好。
如何使用 4.0 版本的 React Router?
React Router 4.0 版本中对 hashHistory 做了迁移,执行包安装命令 npm install react-router-dom 后,按照如下代码进行使用即可。
React 中的 useState()
是什么?
下面说明useState(0)
的用途:
useState
是一个内置的 React Hook。useState(0)
返回一个元组,其中第一个参数count
是计数器的当前状态,setCounter
提供更新计数器状态的方法。咱们可以在任何地方使用setCounter
方法更新计数状态-在这种情况下,咱们在setCount
函数内部使用它可以做更多的事情,使用 Hooks,能够使咱们的代码保持更多功能,还可以避免过多使用基于类的组件。
评论