下面的代码是我的最小问题重现组件。它初始化织物画布,并处理“模式”状态。模式状态决定画布是否可以编辑,并且一个简单的按钮控制该状态。
问题是,即使mode,setMode
工作正常(意思是 - 单击按钮后组件分析器显示正确的状态,按钮内的文本也显示正确的状态),从返回的状态mode
钩子在结构事件回调中,仍然返回初始状态。
我认为问题是由于函数作为回调传递给结构事件造成的。回调似乎以某种方式“缓存”,因此在该回调内,所有状态都有初始值,或者在传递该回调之前处于状态的值。
如何使其正常工作?我想访问结构回调中正确的当前状态。
const [canvas, setCanvas] = useState<fabric.Canvas | null>(null);
const [mode, setMode] = useState("freerun");
const canvasRef = React.useRef<HTMLCanvasElement>(null);
const modes = ["freerun", "edit"];
React.useEffect(() => {
const canvas = new fabric.Canvas(canvasRef.current, {
height: 800,
width: 800,
backgroundColor: 'yellow'
});
canvas.on('mouse:down', function (this: typeof canvas, opt: fabric.IEvent) {
const evt = opt.e as any;
console.log("currentMode", mode) // Not UPDATING - even though components profiler shows that "mode" state is now "edit", it still returns initial state - "freerun".
if (mode === "edit") {
console.log("edit mode, allow to scroll, etc...");
}
});
setCanvas(canvas);
return () => canvas.dispose();
}, [canvasRef])
const setNextMode = () => {
const index = modes.findIndex(elem => elem === mode);
const nextIndex = index + 1;
if (nextIndex >= modes.length) {
setMode(modes[0])
} else {
setMode(modes[nextIndex]);
}
}
return (
<>
<div>
<button onClick={setNextMode}>Current mode: { mode }</button>
</div>
{`Current width: ${width}`}
<div id="fabric-canvas-wrapper">
<canvas ref={canvasRef} />
</div>
</>
)