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 和副作用执行,提高整体性能与稳定性。

相关推荐
崔庆才丨静觅13 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606114 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了14 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅14 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅14 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅15 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment15 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅15 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊15 小时前
jwt介绍
前端
爱敲代码的小鱼15 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax