前端八股文--React篇

# React 知识大纲

# 一、组件基础

# 1.1 React 事件机制

image

# 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 的理解

image

componentWillMountcomponentWillReceiveProps 已经被废弃
原因:异步渲染过程中可能会因为多次调用而导致状态更新不一致

替代方案: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 的生命周期阶段(挂载、更新、卸载、错误处理)

image 挂载阶段(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 中新生命周期

image

# 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)

# 四、组件通信

# 4.1 父子组件的通信方式

# 4.2 跨级组件的通信方式

# 4.3 非嵌套关系组件的通信方式

# 4.4 组件通信的方式总结

# 4.5 解决 props 层级过深的问题

# 五、路由

# 5.1 React-Router 的实现原理

# 5.2 React-Router 的路由模式

# 5.3 React-Router4 路由变化时重新渲染同一个组件的方法

# 5.4 React-Router4 的 Switch 的作用

# 5.5 配置 React-Router 实现路由切换的方法

# 5.7 React-Router 获取 URL 的参数和历史对象的方法

# 5.8 React-Router 设置重定向的方法

# 六、Redux

# 6.1 对 Redux 的理解及解决的问题

# 6.2 Redux 原理及工作流程

# 6.3 Redux 和 Vuex 的区别及共同思想

# 6.4 Redux 中异步请求的处理方法

# 6.5 Redux 实现属性传递的原理

# 6.6 Redux 中间件的定义、参数及作用

# 6.7 Redux 状态管理器和变量挂载到 window 的区别

# 6.8 mobox 和 redux 的区别

# 6.9 Redux 中的 connect 的作用

# 6.10 Redux 请求中间件处理并发的方法

# 6.11 Redux 中间件获取 store 和 action 的方法及处理方式

# 七、Hooks

# 7.1 对 React Hook 的理解及实现原理

# 7.2 为什么 useState 要使用数组而不是对象

# 7.3 React Hooks 解决的问题

# 7.4 useEffect 与 useLayoutEffect 的区别

# 7.5 React Hook 的使用限制

# 7.6 React Hooks 在开发中需要注意的问题及原因

# 7.7 React Hooks 和生命周期的关系

# 八、虚拟 DOM

# 8.1 对虚拟 DOM 的理解、作用及本身的定义

# 8.2 React diff 算法的原理

# 8.3 React key 的作用及解决的问题

# 8.4 虚拟 DOM 与直接操作原生 DOM 的效率比较及原因

# 8.5 React 与 Vue 的 diff 算法的不同

# 九、其他

# 9.1 对 React 和 Vue 的理解及异同

# 9.2 React 中的遍历方法

# 9.3 对 React SSR 的理解

# 9.4 React 要用 JSX 的原因

# 9.5 React 最新版本解决的问题及增加的内容

# 9.6 React 数据持久化的实践

# 9.7 React 的设计思路及理念

# 9.8 React 中 props.children 和 React.Children 的区别

# 9.9 React 的状态提升及使用场景

# 9.10 同时引用 react.js、react-dom.js 和 babel.js 的作用

# 9.11 React.Children.map 和 js 的 map 的区别

# 9.12 React 组件命名的推荐方式

# 9.13 React 实现全局 dialog 的方法

# 9.14 React 页面重新加载时保留数据的方法

# 9.15 React 中使用 async/await 的方法

# 9.16 使用 TypeScript 写 React 应用的方法

# 9.17 React 中 constructor 和 getInitialState 的区别

# 9.18 React 的严格模式的使用方法及用处

# 9.19 为什么使用 jsx 的组件中没看到使用 react 却需要引入 react

# 9.20 HOC 相比 mixins 的优点

# 9.21 React 中的高阶组件运用的设计模式