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

相关推荐
小小小小宇16 分钟前
前端Loader笔记
前端
烛阴1 小时前
从0到1掌握盒子模型:精准控制网页布局的秘诀
前端·javascript·css
前端工作日常4 小时前
我理解的`npm pack` 和 `npm install <local-path>`
前端
李剑一5 小时前
说个多年老前端都不知道的标签正确玩法——q标签
前端
嘉小华5 小时前
大白话讲解 Android屏幕适配相关概念(dp、px 和 dpi)
前端
姑苏洛言5 小时前
在开发跑腿小程序集成地图时,遇到的坑,MapContext.includePoints(Object object)接口无效在组件中使用无效?
前端
奇舞精选5 小时前
Prompt 工程实用技巧:掌握高效 AI 交互核心
前端·openai
用户757582318555 小时前
混合应用开发:企业降本增效之道——面向2025年移动应用开发趋势的实践路径
前端
P1erce5 小时前
记一次微信小程序分包经历
前端