useForceUpdate
强制组件重新渲染的 Hook。
基本用法
实时编辑器
function Demo() { const forceUpdate = useForceUpdate(); const renderCount = useRef(0); renderCount.current += 1; return ( <div> <div style={{ padding: '24px', backgroundColor: 'var(--ifm-color-emphasis-100)', borderRadius: '8px', marginBottom: '12px', textAlign: 'center', }} > <div style={{ fontSize: '48px', fontWeight: 'bold', color: 'var(--ifm-color-primary)' }}> {renderCount.current} </div> <div style={{ fontSize: '14px', color: 'var(--ifm-color-emphasis-700)' }}> 渲染次数 </div> </div> <Button onClick={forceUpdate}>强制重新渲染</Button> </div> ); }
结果
Loading...
更新非响应式数据
强制更新使用 ref 存储的数据:
实时编辑器
function Demo() { const forceUpdate = useForceUpdate(); const dataRef = useRef({ count: 0, items: [] }); const addItem = () => { dataRef.current.items.push(`Item ${dataRef.current.items.length + 1}`); dataRef.current.count += 1; forceUpdate(); // 强制更新以显示新数据 }; return ( <div> <Button onClick={addItem}>添加项目</Button> <div style={{ marginTop: '12px', padding: '16px', backgroundColor: 'var(--ifm-background-surface-color)', border: '1px solid var(--ifm-color-emphasis-300)', borderRadius: '8px', }} > <div style={{ marginBottom: '12px', fontWeight: 'bold' }}> 总计: {dataRef.current.count} 个项目 </div> {dataRef.current.items.map((item, index) => ( <div key={index} style={{ padding: '4px 0' }}> • {item} </div> ))} </div> </div> ); }
结果
Loading...
刷新时间显示
定期强制更新以显示最新时间:
实时编辑器
function Demo() { const forceUpdate = useForceUpdate(); const [auto, setAuto] = useState(false); useDidMount(() => { let timer; if (auto) { timer = setInterval(forceUpdate, 1000); } return () => clearInterval(timer); }); useDidUpdate(() => { let timer; if (auto) { timer = setInterval(forceUpdate, 1000); } else { timer && clearInterval(timer); } return () => clearInterval(timer); }, [auto]); return ( <div> <Group spacing="md"> <Button onClick={forceUpdate}>手动刷新</Button> <Button onClick={() => setAuto(!auto)} variant="outline"> {auto ? '停止自动刷新' : '自动刷新'} </Button> </Group> <div style={{ marginTop: '16px', padding: '20px', backgroundColor: 'var(--ifm-color-emphasis-100)', borderRadius: '8px', textAlign: 'center', }} > <div style={{ fontSize: '24px', fontWeight: 'bold', marginBottom: '8px' }}> {new Date().toLocaleTimeString()} </div> <div style={{ fontSize: '14px', color: 'var(--ifm-color-emphasis-700)' }}> {new Date().toLocaleDateString()} </div> </div> </div> ); }
结果
Loading...
API
参数
function useForceUpdate(): () => void
无参数。
返回值
返回一个函数,调用该函数会强制组件重新渲染。
() => void
工作原理
useForceUpdate 内部使用 useReducer 实现,每次调用都会触发一个新的状态值,从而导致组件重新渲染。
注意事项
- 应该尽量避免使用强制更新
- 优先考虑使用
useState或useReducer管理状态 - 仅在处理非响应式数据(如 ref)时使用
- 过度使用可能导致性能问题
- 不符合 React 的声明式编程范式
替代方案
使用 useState
// ❌ 不推荐
const forceUpdate = useForceUpdate();
const dataRef = useRef(data);
dataRef.current = newData;
forceUpdate();
// ✅ 推荐
const [data, setData] = useState(initialData);
setData(newData);
使用 useReducer
// ❌ 不推荐
const forceUpdate = useForceUpdate();
// 修改复杂状态
forceUpdate();
// ✅ 推荐
const [state, dispatch] = useReducer(reducer, initialState);
dispatch({ type: 'UPDATE', payload: newData });
合理使用场景
- 第三方库集成: 库不支持 React 响应式更新
- 性能优化: 使用 ref 避免不必要的渲染
- 时间/日期显示: 定期刷新当前时间
- 调试: 开发过程中临时使用
- 遗留代码: 迁移 class 组件到函数组件时的过渡方案