无需useState,React组件如何保留变量且不触发重渲染?
React函数组件中实现类似static的持久化变量方案
你需要的是React的useRef钩子,它刚好能满足你的需求:既不会触发组件重渲染,又能在组件多次重渲染之间保留变量值,相当于类组件中this上的实例属性,或者你说的static变量机制。
核心特性对比
- 对比
useState(你的test1):修改useRef的.current属性不会触发组件重渲染,避免了不必要的canvas重绘 - 对比普通
var/let变量(你的test2):组件每次重渲染时,useRef返回的对象都是同一个,存储在.current里的值会被持久保留,不会因为组件重渲染而重置
代码示例(ImagePreview组件)
import { useRef } from 'react'; function ImagePreview() { // 用useRef声明用于canvas绘制的点变量 const point1 = useRef({ x: 0, y: 0 }); const point2 = useRef({ x: 0, y: 0 }); const updatePoint1 = (newX, newY) => { // 修改current属性,无重渲染触发 point1.current = { x: newX, y: newY }; // 直接调用canvas绘制逻辑 drawPoints(); }; const updatePoint2 = (newX, newY) => { point2.current = { x: newX, y: newY }; drawPoints(); }; const drawPoints = () => { const canvas = document.getElementById('preview-canvas'); if (!canvas) return; const ctx = canvas.getContext('2d'); // 清空画布后绘制两个点 ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = '#ff0000'; ctx.beginPath(); ctx.arc(point1.current.x, point1.current.y, 6, 0, Math.PI * 2); ctx.fill(); ctx.fillStyle = '#0000ff'; ctx.beginPath(); ctx.arc(point2.current.x, point2.current.y, 6, 0, Math.PI * 2); ctx.fill(); }; return ( <canvas id="preview-canvas" width={600} height={400} /> ); }
注意事项
useRef.current的变化不会触发组件重渲染,所以如果你的场景不需要依赖这些值更新React元素,完全适用;如果需要同步UI,那还是得结合useState- 不要在组件的render阶段直接修改
useRef.current,建议在事件处理函数、useEffect等副作用钩子中修改
内容的提问来源于stack exchange,提问作者whitebear
相关产品推荐
相关产品推荐

