Graffiti画布更新后形状没有重新渲染怎么办?
在React组件里用Graffiti的Canvas时,通过state更新了形状数据,但画布上的图形没有变化,这是为什么?
我按官方文档写了一个基础组件,用state保存图形数据,通过setShapes更新后控制台显示数据确实变了,但画布还是显示旧图形。尝试过强制更新组件也没用:
function GraffitiContainer() {
const [shapes, setShapes] = useState([]);
const handleAddShape = () => {
const newShape = { type: 'rect', x: 50, y: 50 };
setShapes([...shapes, newShape]); // 数据更新但没渲染
};
return (
<Graffiti
width={800}
height={600}
shapes={shapes} // 这里传递了最新的shapes数组
/>
<button onClick={handleAddShape}>添加矩形</button>
);
}
查看Graffiti文档发现shapes属性是受控组件,但没找到需要手动触发重绘的说明。有没有可能因为React的更新机制导致Graffiti没接收到变化?或者需要给shapes添加key?
shapes加个key,强制让Graffiti重新渲染。下面是改过的代码,复制过去试试:
function GraffitiContainer() {
const [shapes, setShapes] = useState([]);
const handleAddShape = () => {
const newShape = { type: 'rect', x: 50, y: 50, id: Date.now() }; // 加个唯一id
setShapes([...shapes, newShape]);
};
return (
height={600}
shapes={shapes}
key={shapes.length} // 用shapes长度作为key,确保每次更新都改变key
/>
);
}
这里的关键点有两个:
1. 给每个形状加了个
id字段,值是时间戳Date.now(),这样每个形状都有唯一标识,避免潜在的重复问题。2. 在
Graffiti组件上加了key属性,绑定了shapes.length。只要shapes数组长度变化,React就会认为这是个新组件,强制重新渲染。如果还是不行,那就可能是Graffiti内部有自己的一套状态管理机制,需要手动触发重绘。可以查下它的API文档,看有没有类似
forceUpdate或者refresh的方法。实在搞不定的话,也可以换个思路,直接用
ref操作Canvas的原生API,绕开这些坑。不过那是另一个话题了。shapes属性,但内部是否监听了 props 变化并触发重绘,这个是关键。从你贴的代码看,
shapes是传进去了,但你少了一个关键操作:**通知 Graffiti 组件去 redraw**。Graffiti 的官方文档里有个隐藏的点:当你用受控模式更新
shapes,必须调用redraw()方法才会触发重绘。否则它内部不会自动刷新。你可以这样改:
另外,
shapes不需要加 key,因为 Graffiti 并不是靠 key 来判断是否更新的。总结下:React 的 state 更新没问题,但 Graffiti 不是自动重绘的 canvas,得手动调
redraw(),否则它就“睡着了”。这种手动刷新的机制在 canvas 类库中挺常见的。