# React 知识大纲
# 一、组件基础
# 1.1 React 事件机制
# 1.2 React 高阶组件、Render props、hooks 的区别及迭代原因
https://github.com/z-memo/interview/issues/219 (opens new window)
# 1.3 对 React-Fiber 的理解及解决的问题
# 1.4 React 高阶组件的定义、与普通组件的区别及适用场景
# 1.5 触发 React 重新渲染的方法及重新渲染时 render 的作用
# 1.6 有状态组件和无状态组件的理解与使用场景
有状态组件
定义:在组件内部能够维护和管理状态(state)的组件
- 需要处理用户交互
- 复杂的业务逻辑和状态管理
无状态组件
定义:组件内部没有自己的状态(它只接收外部传入的属性(props),并根据这些属性来渲染输出,无状态组件是一个纯函数,对于相同的输入(即相同的属性),它总是返回相同的输出)
- 展示静态数据或简单的动态数据(基于传入属性)
- 方便用于组合和复用
- 有利于react性能优化(无状态组件是可预测的。如果组件不变,props不变,就不需要重新render)
# 1.7 React 中的受控组件和非控组件
# 1.8 类组件与函数组件的异同
# 1.9 React 的事件与普通 HTML 事件的不同
# 1.10 React.createClass 和 extends Component 的区别
# 1.11 React 判断重新渲染组件的方式
# 1.12 对 React 中 Fragment 的理解及使用场景
# 1.13 React 获取组件对应的 DOM 元素的方法
ref
# 1.14 对 React 的插槽(Portals)的理解、使用方法及场景
可以让一个组件的内容 “跳出” 它原本所在的组件层级,出现在页面的其他位置
ReactDOM.createPortal(<Comp/>, document.body)
主要用于弹窗浮层中
# 1.15 在 React 中避免不必要 render 的方法
# 1.16 对 React-Intl 的理解及工作原理
# 1.17 对 React context 的理解
# 1.18 React 中绑定 this 的其他方式
# 1.19 React 组件中事件代理的方法及原理
# 1.20 React.Component 和 React.PureComponent 的区别
# 1.21 Component, Element, Instance 之间的区别与联系
# 1.22 React 声明组件的方法及区别
# 1.23 React 中在 render 访问 refs 的情况及原因
# 1.24 为什么 React 不推荐优先考虑使用 Context
# 1.25 React 中 refs 的作用及应用场景
# 1.26 React 组件的构造函数的作用及必要性
- 继承父类React.Component,使用Super关键字
- 初始化state,mounted之前的默认值
- 绑定函数
fn.bind(this)
# 1.27 对 componentWillReceiveProps 的理解
componentWillMount
和componentWillReceiveProps
已经被废弃
原因:异步渲染过程中可能会因为多次调用而导致状态更新不一致
替代方案:getDerivedStateFromProps
static getDerivedStateFromProps(props, state) {
if (props.initialValue!== state.count) {
// 可以一步获取接口数据
// 但是不能获取组件实例this
return { count: props.initialValue };
}
return null;
}
# 1.28 React.forwardRef 的定义及作用
forwardRef 允许组件使用 ref 将 DOM 节点暴露给父组件
用法:
- 将 DOM 节点暴露给父组件
- 在多个组件中转发 ref
- 暴露命令式句柄(结合useImperativeHandle)
const SomeComponent = forwardRef(render)
const MyInput = forwardRef(function MyInput(props, ref) {
return (
<label>
{props.label}
<input ref={ref} />
</label>
);
});
不应该滥用ref,这些场景可以使用:滚动到节点、将焦点放在节点上、触发动画,以及选择文本等等
如果可以将某些东西使用 props 表达,那就不应该使用 ref
# 二、数据管理
# 2.1 React setState 调用的原理
一句话介绍:调用setState,更新state,从而更新UI
原理:
异步更新: React为了提高性能,不可能更改state之后,同步更新UI,所以这是一个异步的过程
批处理: 每次调用setState,会提交一个更新state队列,在合适的时机对这些队列进行批处理
# 2.2 React setState 调用之后的情况(同步或异步)
分情况
React 18 之前
合成事件系统之内的是异步更新,之外是同步更新
如setTimeout,直接绑定在dom上的事件,this.setState回调函数,都是同步更新
React 18 之后
实现了自动批处理,setTimeout,直接绑定在dom上的事件,
# 2.3 React 组件中 this.state 和 setState 的区别
this.state提供了读的能力
this.state必须通过setState来修改
# 2.4 React 组件的 state 和 props 的区别
state | props | |
---|---|---|
定义 | 组件内部存储的状态 | 从父组件传递给子组件的数据 |
数据流向 | 组件内部更新 | 从父组件更新 |
可变性 | 通过setState更新 | 只读,子组件不能修改 |
# 2.5 React 中的 setState 批量更新的过程
- 更新队列的创建
- 事件处理函数结束后,生命周期后会触发 批量更新
- diff算法,更新dom
# 2.6 React 中 getDefaultProps 的作用
# 2.7 React 中 props 只读的原因
# 2.8 React 中组件的 props 改变时更新组件的方法
# 2.9 React 中 setState 的第二个参数作用
# 2.10 state 从 reducer 到组件的注入过程
# 2.11 React 中检验 props 的方法及目的
# 2.12 React 中的 setState 和 replaceState 的区别
# 三、生命周期
# 3.1 React 的生命周期阶段(挂载、更新、卸载、错误处理)
挂载阶段(Mounting)
- constructor()
- static getDerivedStateFromProps(props, state)
- render()
- componentDidMount()
更新阶段(Updating)
- static getDerivedStateFromProps(props, state)
- shouldComponentUpdate(nextProps, nextState)
- render()
- componentDidUpdate(prevProps, prevState, snapshot)
卸载阶段(Unmounting)
- componentWillUnmount()
错误处理阶段(Error Handling)
- static getDerivedStateFromError(error)
- componentDidCatch(error, errorInfo)
# 3.2 React 性能优化的生命周期及原理
shouldComponentUpdate
shouldComponentUpdate(nextProps, nextState) {
if (nextProps.number === this.props.number && nextState.square === this.state.square) {
return false;
}
return true;
}
React.memo PureComponent 原理是在shouldComponentUpdate 做了浅比较
useMemo 缓存复杂计算
useCallback 适合用于React.memo 优化的情况
# 3.3 state 和 props 触发更新的生命周期区别
state更新流程
- 更新操作放入更新队列(在 React 18 中会进行自动批处理)
- 对于类组件,shouldComponentUpdate被触发
- render
- componentDidUpdate
props更新流程
- static getDerivedStateFromProps
- shouldComponentUpdate
- render
- componentDidUpdate
# 3.4 React 中发起网络请求的生命周期及原因
- componentDidMount
- componentDidUpdate 发起网络请求时,需要进行条件判断,以避免无限循环的请求。 如:根据关键词更新搜索结果时,可以在componentDidUpdate中判断关键词是否变化,如果变化则发起网络请求获取新的搜索结果
# 3.5 React 16 中新生命周期
# 3.6 React 废弃的生命周期及原因
componentWillMount废弃的原因
React 一直在向异步渲染方向发展。在异步渲染环境下,componentWillMount的执行时机变得模糊。它原本是在组件挂载到 DOM 之前调用,主要用于初始化组件状态或执行一些只需要执行一次的操作。但随着异步渲染的引入,组件可能会被暂停、恢复或者重新排序渲染,这使得componentWillMount的执行顺序和时间难以预测。例如,在服务器端渲染(SSR)与客户端渲染(CSR)结合的场景中,componentWillMount可能会在服务器端和客户端分别执行,这可能导致意外的行为。
componentWillReceiveProps废弃的原因
容易引发复杂的状态更新逻辑
React 引入了static getDerivedStateFromProps来替代其部分功能。static getDerivedStateFromProps是一个静态方法,它接收props和state作为参数,并且必须返回一个用于更新state的对象或者null。这种方式使得状态更新更加可控和可预测,避免了componentWillReceiveProps可能出现的副作用和复杂的更新逻辑
componentWillUpdate废弃的原因
异步渲染导致的不确定性
# 3.7 React 16.X 中 props 改变后处理的生命周期
- static getDerivedStateFromProps(props, state)
- shouldComponentUpdate(nextProps, nextState)
- render()
- componentDidUpdate(prevProps, prevState)