前端面试准备指南四之React篇


一、React Key的作用

1.1 Key的定义

Keys 是 React 用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识。

1.2 Key的作用

  • 帮助 React 识别哪些元素发生了变化
  • 提高 diff 算法的效率
  • 避免不必要的重新渲染

1.3 有Key与没Key的区别

情况 有Key 没Key
列表更新 精确定位变化的元素 可能导致错误的重新渲染
元素复用 根据Key匹配原有元素 无法匹配,可能创建新元素
性能 更高 可能性能下降

1.4 同一层级节点比较

React 的 diff 算法只在同一层级的节点之间进行比较:

  • 相同Key :认为是同一个节点,比较属性变化
  • 不同Key :认为是新节点,执行插入/删除操作
  • 跨层级 :无法移动,只能删除旧节点、创建新节点

1.5 最佳实践

  • 使用稳定的唯一ID作为Key
  • 避免使用数组下标作为Key(会导致渲染错误)
  • 避免使用随机数作为Key

二、虚拟DOM与Diff算法

2.1 虚拟DOM定义

虚拟DOM 本质上是 JavaScript 对象,是对 真实DOM 的抽象表现。

const vdom = {
    type: "div",
    props: { className: "container", children: "Hello" },
};

2.2 虚拟DOM优势

  • 减少直接操作DOM,提高性能
  • 跨平台能力更强(SSR、Native等)
  • 批量更新,减少重排重绘

2.3 Diff算法流程

  1. 状态变更 :记录新树和旧树的差异
  2. 对比差异 :通过diff算法找出最小更新点
  3. 批量更新 :将差异更新到真正的DOM中

2.4 render函数原理

  1. 根据 tagName 生成父标签,读取 props,设置属性
  2. 如果有 content,设置 innerHTML 或 innerText
  3. 如果存在子元素,遍历子元素递归调用 render 方法
  4. 将生成的子元素依次添加到父元素中,返回根元素

2.5 Diff算法优化策略

  • 同级比较 :只比较同层级的节点
  • 类型比较 :不同类型节点直接替换
  • Key匹配 :通过Key精确匹配节点

三、组件通信方式

3.1 父子组件通信

父->子通信 :

  • 使用 props 传递数据
;

function ChildComponent(props) {
    return 
{props.name}
; }

子->父通信 :

  • 使用回调函数传递数据
function Parent() {
    const handleData = data => console.log(data);
    return ;
}

function Child({ onData }) {
    return ;
}

父调用子方法 :

  • 使用 ref 获取子组件实例
const childRef = useRef();
childRef.current.handleMethod();

3.2 兄弟组件通信

通过父组件中转 :

  • 状态提升到父组件,子组件通过props和回调通信

使用状态管理库 :

  • Redux、MobX、Zustand 等

发布订阅模式 :

  • 使用 EventEmitter 或自定义事件系统

3.3 跨级组件通信

Context API :

const ThemeContext = React.createContext("light");

function App() {
    return (
        
            
        
    );
}

function ThemedButton() {
    const theme = useContext(ThemeContext);
    return ;
}

3.4 现代状态管理方案

方案 特点 适用场景
Zustand 轻量级,API简洁 中小型应用
Jotai 原子化状态管理 细粒度状态管理
Recoil Facebook开发 大型应用

3.5 组件组合

将子组件作为 children 或 render prop 传递,避免过度使用 Context:

function Card({ children }) {
    return 
{children}
; } function MouseTracker({ render }) { return
{render(mousePosition)}
; }

四、JSX解析

4.1 JSX本质

JSX 是 JavaScript 的语法扩展,React 使用它来描述 UI 结构。

4.2 编译过程

JSX 通过编译器(如 Babel)转换为 React.createElement 函数调用:

const element = 
Hello
; const element = React.createElement("div", { className: "greeting" }, "Hello");

4.3 createElement参数

React.createElement(
    type, // 元素类型
    props, // 元素属性
    children // 子元素
);

五、React生命周期

5.1 类组件生命周期

挂载阶段 :

钩子 说明
constructor 组件实例创建
getDerivedStateFromProps 从props派生state(静态方法)
render 渲染组件
componentDidMount 组件挂载完成

更新阶段 :

钩子 说明
getDerivedStateFromProps props变化时更新state
shouldComponentUpdate 决定是否重新渲染
render 重新渲染
getSnapshotBeforeUpdate 获取更新前快照
componentDidUpdate 组件更新完成

卸载阶段 :

钩子 说明
componentWillUnmount 组件卸载前清理

5.2 错误处理生命周期

钩子 说明
getDerivedStateFromError 捕获子组件错误(静态方法)
componentDidCatch 实例方法,记录错误信息

5.3 废弃的生命周期

  • componentWillMount、componentWillReceiveProps、componentWillUpdate
  • React 16 标记为 UNSAFE_
  • React 18 完全移除

5.4 Hooks生命周期(函数组件)

类组件钩子 Hook
componentDidMount useEffect(() => {}, [])
componentDidUpdate useEffect(() => {}, [deps])
componentWillUnmount useEffect(() => { return () => {} }, [])
useEffect(() => {
    console.log("mounted");
    return () => console.log("cleanup");
}, []);

5.5 useLayoutEffect

  • 与 useEffect 类似,但同步执行
  • 在 DOM 更新后同步执行,用于DOM测量

六、React性能优化

6.1 渲染优化

函数组件优化 :

Hook 作用
React.memo 缓存组件渲染结果
useMemo 缓存计算结果
useCallback 缓存函数引用
const MemoizedComponent = React.memo(Component);

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

const memoizedCallback = useCallback(() => {
    doSomething(a, b);
}, [a, b]);

类组件优化 :

  • 使用 PureComponent 自动进行浅比较
  • 实现 shouldComponentUpdate 自定义比较逻辑

通用优化 :

  • 使用稳定的 key 值
  • 避免在 render 中创建新对象、新函数
  • 保持 props 和 state 扁平化
  • 使用 return null 代替 display: none

6.2 长列表优化

  • 虚拟滚动:react-window、react-virtualized
  • 分页加载或无限滚动

6.3 图片优化

  • 懒加载图片
  • 使用适当尺寸的图片
  • 使用 WebP 格式

6.4 动画优化

  • 使用 transform 和 opacity 实现动画
  • 使用 requestAnimationFrame 优化动画性能
  • 避免布局抖动

6.5 代码分割

const LazyComponent = React.lazy(() => import("./LazyComponent"));

function App() {
    return (
        }>
            
        
    );
}

6.6 Concurrent Mode优化

  • useTransition:标记非紧急更新
  • useDeferredValue:延迟处理非紧急状态

6.7 构建优化

  • 使用 esbuild 或 swc 加速构建
  • 配置合理的 sourcemap
  • 压缩和混淆代码
  • 提取 CSS 到单独文件

七、this绑定

7.1 绑定方式对比

方式 写法 性能 推荐度
bind方法 this.handleClick = this.handleClick.bind(this) 每次渲染创建新函数 中
箭头函数 onClick={() => this.handleClick()} 每次渲染创建新函数 中
类属性 handleClick = () => {} 只创建一次 高

7.2 推荐写法

class MyComponent extends React.Component {
    handleClick = () => {
        console.log(this);
    };
}

八、React 18新特性

8.1 并发特性

特性 说明
时间切片 将渲染拆分为小任务,优先处理用户交互
Suspense 支持组件级别代码分割和数据获取
useTransition 标记非紧急更新
useDeferredValue 延迟处理非紧急状态

8.2 自动批处理

  • 所有状态更新都会被批处理
  • 包括 setTimeout、Promise 回调中的更新

8.3 新根API

import { createRoot } from "react-dom/client";
const root = createRoot(document.getElementById("root"));
root.render();

8.4 服务端组件

  • 服务端渲染组件,减少客户端包体积
  • 支持直接访问后端数据

8.5 其他改进

Hook 说明
useId 生成唯一ID
useSyncExternalStore 订阅外部状态
useInsertionEffect CSS-in-JS优化

8.6 现代渲染策略

策略 说明
Streaming SSR 流式服务端渲染,逐步发送HTML,减少首屏时间
SSG 静态站点生成,构建时预渲染页面
ISR 增量静态再生,运行时按需重新生成页面

九、React Fiber

9.1 Fiber架构目的

React Fiber 是 React 16 引入的新的调和算法,解决同步渲染阻塞问题。

9.2 核心特性

特性 说明
增量渲染 将渲染拆分为小单元
优先级调度 根据任务优先级安排执行顺序
可中断 允许处理更高优先级任务
时间切片 空闲时间执行渲染任务

9.3 Fiber工作流程

  1. Render阶段 :生成Fiber树,确定需要更新的内容
  2. Commit阶段 :执行DOM操作

十、setState同步异步

10.1 合成事件与钩子函数

在合成事件和钩子函数中,setState 是”异步”的:

this.setState({ count: this.state.count + 1 });
console.log(this.state.count);

this.setState({ count: this.state.count + 1 }, () => {
    console.log(this.state.count);
});

10.2 原生事件与setTimeout

在原生事件和 setTimeout 中,setState 是同步的:

document.getElementById("btn").addEventListener("click", () => {
    this.setState({ count: this.state.count + 1 });
    console.log(this.state.count);
});

setTimeout(() => {
    this.setState({ count: this.state.count + 1 });
    console.log(this.state.count);
}, 0);

10.3 批量更新

  • 同一值的多次 setState 会被覆盖
  • 不同值的 setState 会合并批量更新

10.4 异步原理揭秘

setState 的”异步”并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿到更新后的值,形成了所谓的”异步”,当然可以通过第二个参数 setState(partialState, callback) 中的 callback 拿到更新后的结果。

十一、Redux核心概念

11.1 数据流

用户行为 → Action → Reducer → Store → View

11.2 核心组成

组成 说明
Store 存储所有状态
Action 描述发生的事件
Reducer 根据Action更新状态

11.3 React-Redux

组件 说明
Provider 从最外部封装整个应用,传递store
Connect 连接React组件与Redux store

Connect 的工作原理 :

  1. 包装原组件,将 state 和 action 通过 props 的方式传入到原组件内部
  2. 监听 store tree 变化,使其包装的原组件可以响应 state 变化

十二、高阶组件

12.1 定义

高阶组件是参数为组件,返回值为新组件的函数。

function withAuth(WrappedComponent) {
    return function WithAuthComponent(props) {
        if (isAuthenticated) {
            return ;
        }
        return ;
    };
}

12.2 作用

  • 代码复用,逻辑抽象
  • 渲染劫持
  • State 抽象和更改
  • Props 更改

十三、创建组件的方式

13.1 函数组件(推荐)

const Counter = () => {
    const [count, setCount] = useState(0);

    useEffect(() => {
        document.title = `Count: ${count}`;
    }, [count]);

    return (
        

{count}

); };

13.2 类组件

class Counter extends React.Component {
    state = { count: 0 };

    increment = () => {
        this.setState({ count: this.state.count + 1 });
    };

    render() {
        return (
            

{this.state.count}

); } }

13.3 现代组件写法

写法 说明
React.memo 缓存函数组件渲染
forwardRef 传递ref给子组件
lazy 动态导入组件

十四、元素与组件的区别

概念 说明
React元素 普通对象,描述UI结构
组件 类或纯函数,由元素构成

十五、React核心特点

15.1 核心思想

  • React :函数式编程,单向数据流,数据不可变
  • 对比:Vue 采用响应式系统,数据驱动视图

15.2 模板语法

  • React :使用 JSX,将 HTML 与 JavaScript 结合,更灵活
  • 对比:Vue 使用 HTML-like 模板语法,支持指令

15.3 状态管理

方案 特点 适用场景
Redux 成熟稳定,生态完善 大型应用
Zustand 轻量级,API简洁 中小型应用
Jotai 原子化状态管理 细粒度状态管理

15.4 性能优化

优化方式 说明
memo/useMemo/useCallback 手动优化渲染性能
并发模式 React 18 新特性
编译时优化 Tree Shaking、静态提升

15.5 适用场景

  • 大型应用
  • 复杂状态管理需求
  • 需要良好的 TypeScript 支持

十六、Redux与Vuex对比

16.1 核心区别

对比项 Redux Vuex
数据可变性 不可变,每次返回新state 可变,直接修改
变化检测 订阅机制触发更新通知 getter/setter监听
适用框架 React Vue

文章作者: 弈心
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 弈心 !
赏
评论
 上一篇
前端面试准备指南一之HTML&CSS篇 前端面试准备指南一之HTML&CSS篇
HTML与CSS核心知识点,包括HTML5新特性、浏览器渲染机制、CSS布局、动画等
下一篇 
前端面试准备指南六之前端工程化篇 前端面试准备指南六之前端工程化篇
前端工程化核心知识点,涵盖模块化规范、Webpack构建工具、构建优化及工程化最佳实践,包括CommonJS/AMD/CMD/ES Module、Webpack配置/Loader/Plugin、代码分割、Tree Shaking、CI/CD等
  目录