React中可有可无的优化-对象类型的使用

js 复制代码
export const emptyObject = {}
export const emptyArray = []
export const noop = () => {}

在前端开发(尤其是 React、Vue 等现代框架)中非常常见,它们的作用是提升性能和避免不必要的渲染。下面我们来详细解释这三行代码的原理、用途以及可能的扩展用法。


✅ 一、emptyObject = {}

原理:

  • 创建一个空对象字面量 {}
  • 因为它是 const 定义的常量,在整个应用生命周期中地址不会变(即引用不变)。

用途:

  • 防止组件因 props 引用变化而重新渲染
  • 在 React 或 Vue 中,如果父组件传给子组件的对象每次都是新的 {},即使内容一样,也会触发不必要的 diff 和 render。

示例场景(React):

jsx 复制代码
function MyComponent({ config = {} }) { ... }

上面写法每次调用组件时都会创建一个新的 {},导致 config 的引用变化,从而引起不必要的更新。

改为:

jsx 复制代码
import { emptyObject } from './utils'

function MyComponent({ config = emptyObject }) { ... }

这样无论多少次调用,只要没有传入 config,默认值始终指向同一个内存地址,不会触发更新。


✅ 二、emptyArray = []

原理:

  • 同上,创建一个空数组字面量 [],且引用固定不变。

用途:

  • 防止因数组引用变化引起的不必要更新或副作用执行。
  • 常用于 useEffectuseMemouseCallback 的依赖项数组中,或者作为默认值传递给子组件。

示例场景(React):

js 复制代码
useEffect(() => {
  // do something
}, [list]) // 如果 list 是 [] 每次都新生成,会不断触发 effect

优化方式:

js 复制代码
import { emptyArray } from './utils'

const list = data || emptyArray

✅ 三、noop = () => {}

原理:

  • noop 是 "no operation" 的缩写,表示一个空函数
  • 这个函数不做任何事情,返回 undefined

用途:

  • 当某些 API 要求必须传一个回调函数但你不希望它做任何事时使用。
  • 防止因为传入 undefined 导致运行时报错。
  • 提高性能:避免临时定义匿名函数造成额外开销(如在循环中)。

示例场景(React):

jsx 复制代码
<MyButton onClick={onSubmit || () => {}} />

优化为:

jsx 复制代码
import { noop } from './utils'

<MyButton onClick={onSubmit || noop} />

其他常见用途:

  • 占位函数(防止 undefined)
  • 默认事件处理器
  • 单元测试中 mock 函数

🧠 总结对比表:

名称 类型 是否可变 主要作用 使用场景示例
emptyObject Object ❌ 不可变 避免对象引用变化造成的重渲染 默认 props
emptyArray Array ❌ 不可变 防止数组引用变化导致 useEffect 执行 默认列表数据
noop Function ❌ 不可变 占位函数,防止 undefined 错误 空回调函数

🔍 扩展建议

1. 抽象成工具库(utils.js)

你可以统一导出这些"不可变默认值"供项目全局使用:

js 复制代码
// utils.js
export const emptyObject = {}
export const emptyArray = []
export const noop = () => {}
export const identity = x => x
export const alwaysTrue = () => true
export const alwaysFalse = () => false

2. 在 TypeScript 中增强类型

为了更好的类型安全,可以加上类型注解:

ts 复制代码
export const emptyObject: Record<string, never> = {}
export const emptyArray: readonly never[] = []
export const noop: () => void = () => {}

3. 在 React hooks 中使用

tsx 复制代码
import { useMemo, useCallback } from 'react'
import { emptyObject, emptyArray, noop } from './utils'

function useCustomHook(data = emptyArray) {
  const processedData = useMemo(() => process(data), [data])
  const handleClick = useCallback(noop, [])
}

📌 小贴士

  • 这些技巧属于微优化,在大型项目或高频更新组件中特别有效。
  • 不推荐过度使用,比如对简单组件没必要刻意替换 {}
  • 在 Redux selector、React Query、SWR 等状态管理中也广泛使用类似模式。

如果你正在开发一个大型 React/Vue 应用,合理使用 emptyObjectemptyArraynoop 可以显著减少不必要的 re-render 和副作用执行,提高整体性能与稳定性。

相关推荐
DoraBigHead1 分钟前
小哆啦解题记——两数失踪事件
前端·算法·面试
一斤代码5 小时前
vue3 下载图片(标签内容可转图)
前端·javascript·vue
中微子6 小时前
React Router 源码深度剖析解决面试中的深层次问题
前端·react.js
光影少年6 小时前
从前端转go开发的学习路线
前端·学习·golang
中微子6 小时前
React Router 面试指南:从基础到实战
前端·react.js·前端框架
3Katrina6 小时前
深入理解 useLayoutEffect:解决 UI "闪烁"问题的利器
前端·javascript·面试
前端_学习之路7 小时前
React--Fiber 架构
前端·react.js·架构
coderlin_7 小时前
BI布局拖拽 (1) 深入react-gird-layout源码
android·javascript·react.js
伍哥的传说7 小时前
React 实现五子棋人机对战小游戏
前端·javascript·react.js·前端框架·node.js·ecmascript·js
qq_424409197 小时前
uniapp的app项目,某个页面长时间无操作,返回首页
前端·vue.js·uni-app