useForceUpdate

package version >0.2.0

shadcn any version

author: cmtlyt

update time: 2026/04/07 11:16:55

强制组件重新渲染的 Hook。当组件状态或 props 没有变化,但需要触发重新渲染时使用。

Features

  • 轻量级: 基于 useReducer 实现,无额外依赖
  • 高性能: 使用计数器机制避免数值无限增长
  • 类型安全: 完整的 TypeScript 类型支持
  • 简单易用: 返回一个函数,调用即可触发重渲染

Install

npm
npm i @cmtlyt/lingshu-toolkit
shadcn
npx shadcn@latest add https://cmtlyt.github.io/lingshu-toolkit/r/reactUseForceUpdate.json

Usage

import { useForceUpdate } from '@cmtlyt/lingshu-toolkit/react'
// or
import { useForceUpdate } from '@cmtlyt/lingshu-toolkit/react/use-force-update'

Basic Example

基础用法:调用返回的函数即可强制组件重新渲染。

import { useForceUpdate } from '@cmtlyt/lingshu-toolkit/react'

function BasicExample() {
  const forceUpdate = useForceUpdate()
  const [timestamp, setTimestamp] = useState(Date.now())

  const handleClick = () => {
    setTimestamp(Date.now())
    forceUpdate() // 强制重新渲染
  }

  return (
    <div>
      <p>当前时间: {new Date(timestamp).toLocaleString()}</p>
      <button onClick={handleClick}>强制更新</button>
    </div>
  )
}

Advanced Examples

与外部状态结合

在需要响应外部状态变化,但又不想将其放入 React state 时使用。

import { useForceUpdate } from '@cmtlyt/lingshu-toolkit/react'

function ExternalStateExample() {
  const forceUpdate = useForceUpdate()
  const externalData = useRef({ value: 0 })

  const updateExternal = () => {
    externalData.current.value += 1
    forceUpdate() // 响应外部状态变化
  }

  return (
    <div>
      <p>外部值: {externalData.current.value}</p>
      <button onClick={updateExternal}>更新外部值</button>
    </div>
  )
}

强制重新计算派生值

当依赖的值变化但 React 无法检测到时使用。

import { useForceUpdate } from '@cmtlyt/lingshu-toolkit/react'

function DerivedValueExample() {
  const forceUpdate = useForceUpdate()
  const dataRef = useRef({ count: 0, items: [] })

  const addItem = () => {
    dataRef.current.items.push(`Item ${dataRef.current.count}`)
    dataRef.current.count += 1
    forceUpdate() // 强制重新渲染以显示新数据
  }

  return (
    <div>
      <h3>列表项数: {dataRef.current.items.length}</h3>
      <ul>
        {dataRef.current.items.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
      <button onClick={addItem}>添加项</button>
    </div>
  )
}

性能优化场景

在某些性能优化场景中,避免不必要的 state 更新。

import { useForceUpdate } from '@cmtlyt/lingshu-toolkit/react'

function PerformanceExample() {
  const forceUpdate = useForceUpdate()
  const cacheRef = useRef(new Map())

  const getData = (key: string) => {
    if (!cacheRef.current.has(key)) {
      cacheRef.current.set(key, fetchDataFromAPI(key))
      forceUpdate() // 数据加载完成后强制更新
    }
    return cacheRef.current.get(key)
  }

  return (
    <div>
      <button onClick={() => getData('data1')}>加载数据</button>
    </div>
  )
}

API

返回值

返回一个函数,调用该函数会强制组件重新渲染。

type ForceUpdateFunction = () => void

function useForceUpdate(): ForceUpdateFunction

使用场景

1. 响应非 React 状态变化

当使用 useRef 或其他非 React 状态管理方式存储数据,需要在数据变化时触发 UI 更新。

2. 第三方库集成

某些第三方库使用回调或事件通知状态变化,而不是遵循 React 的响应式模式。

3. 强制重新计算

当组件的渲染依赖于某些计算密集型操作,而这些操作的结果没有通过 state 管理时。

4. 调试和测试

在开发过程中,用于强制组件重新渲染以验证某些行为。

注意事项

⚠️ 注意事项

  1. 谨慎使用: 大多数情况下,应该使用 React 的标准状态管理方式(useStateuseReducer 等),useForceUpdate 应该作为最后的手段。

  2. 性能影响: 频繁强制更新可能导致性能问题,因为它会绕过 React 的优化机制。

  3. 可维护性: 过度使用 useForceUpdate 会使代码难以理解和维护,因为它破坏了 React 的响应式编程模型。

  4. 最佳实践: 在使用 useForceUpdate 之前,考虑以下替代方案:

    • 将数据移入 useStateuseReducer
    • 使用 Context API 管理共享状态
    • 使用状态管理库(如 Redux、Zustand 等)

🔧 执行机制

  • 内部使用计数器机制触发组件重新渲染
  • 自动管理计数器以避免数值无限增长
  • 不依赖状态值,仅利用触发重新渲染的副作用