在Fabrijs的回调中,反应状态始终返回前一个(或初始)状态 [英] React state always returning previous (or initial) state inside callback from fabricjs

查看:17
本文介绍了在Fabrijs的回调中,反应状态始终返回前一个(或初始)状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码是我的最小问题再现组件。它初始化Fabric Canvas,并处理&模式和状态。模式状态确定是否可以编辑画布,并由一个简单的按钮控制该状态。

问题是,即使mode,setMode正常工作(意味着-组件分析器在按钮单击后显示正确的状态,按钮内的文本也显示正确的状态),modeFabric事件回调中的钩子返回的状态仍然返回初始状态。

我认为问题是因为函数作为回调传递到Fabric事件。回调似乎以某种方式缓存了,因此在该回调中,所有状态都有初始值,或者在传递该回调之前处于状态中的值。

如何使其正常工作?我希望能够访问交换矩阵内部正确的当前状态回调。

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>
</>
)

推荐答案

问题是mode在回调创建期间被读取,其值保存在回调中,从此再也不会更新。

为了解决此问题,您必须在useEffect依赖项上添加mode。这样,每次mode更改反应将再次运行useEffect,回调将接收更新(和正确)值。

这篇关于在Fabrijs的回调中,反应状态始终返回前一个(或初始)状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆