React 状态总是从 Fabricjs 的回调中返回先前(或初始)状态

2024-05-11

下面的代码是我的最小问题重现组件。它初始化织物画布,并处理“模式”状态。模式状态决定画布是否可以编辑,并且一个简单的按钮控制该状态。

问题是,即使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>
</>
)


问题是mode被读取,并且它的值在回调创建期间保存在回调内,并且从那时起,不再更新。

为了解决这个问题,你必须添加mode on the useEffect依赖关系。每次这样mode更改React将再次运行useEffect并且回调将收到更新的(和正确的)值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React 状态总是从 Fabricjs 的回调中返回先前(或初始)状态 的相关文章

随机推荐

  • 字符串排序真的是 O(n^2logn) 吗? [复制]

    这个问题在这里已经有答案了 我读了以下内容 排序需要 O NlogN 那么它怎么是 O N 2logN 我们在这里想念的是 两个字符串的比较不是 O 1 在最坏的情况下 需要 在 所以最终的复杂度是O N 2logN 它是否正确 我一直认为
  • CSS 列数导致项目拆分列

    尝试不使用 jQuery 脚本来实现砖石效果 因此寻找 CSS 替代方案 我正在尝试使用列计数 这似乎有效 但不符合预期 因此 列就在那里 但有时容器中的项目会被拆分为多个列 正如您应该在此示例中看到的那样 http jsfiddle ne
  • AWS 从实例元数据检索安全凭证

    这不是问题的重复使用 API 调用获取我的 AWS 凭证 https stackoverflow com q 34810642 850848 因为我具体询问亚马逊在他们给出的示例中的含义 我正在看这里 http docs aws amazo
  • WiX - 安装 Windows 服务以在 x64 模式下运行

    我正在使用 WiX 3 5 及其 ServiceInstall 标签安装 Windows 服务
  • 警告:格式“%d”需要类型“int *”,但参数 2 的类型为“int”

    所以我是 C 的新手 并且对这个警告发生的情况遇到了麻烦 该警告是什么意思以及我该如何解决它 我写的代码在这里 void main void char name int age 0 printf input your name n scan
  • Java SWT 用户输入验证

    在 SWT 中进行用户输入验证时 Java 约定是什么 我读到有 FieldEditors 它们是非常方便的字段 但遗憾的是仅适用于首选项和对话框 我还了解到有一个 IValidator 接口 但它经常与数据绑定一起使用 就我而言 我的大多
  • Android - 在通知栏中使用外部个人资料图像,如 Facebook

    我知道您可以在推送通知参数中发送信息 例如消息 标题 图像 URL 等 Facebook 如何在通知区域中显示您的个人资料图片和消息 我想在通知区域中使用外部图像 因此当您将其下拉时 您会看到带有消息的个人资料图像 现在 我的仅显示可绘制文
  • 为什么 Azure Key Vault 安全?

    Azure Key Vault 为什么或如何安全 我需要在服务器上存储密钥 URI 客户端 ID 和客户端密钥 因此如果任何人授予对托管应用程序的服务器的访问权限 他将能够访问存储在 Key Vault 中的密钥和密钥 这意味着将它们存储在
  • Cloud Functions for Firebase 中的套接字挂起错误

    我有一个由 Pub Sub 事件触发的云函数 它用请求 承诺 https github com request request promise从我用于数据的 API 发出多个 GET 请求 它在 Cloud Functions Emulat
  • 如何将 BOOST_FOREACH 与两个 std::map 一起使用?

    我的代码基本上如下所示 std map
  • 导入 IronPython 的嵌入式库

    我已通过 NuGet 将 IronPython 标准库添加到我的 c net4 项目中 后来获得了一些参考资料 IronPython IronPython Modules IronPython SQLite IronPython Wpf M
  • 为什么有些网站在 iPad 上无法缩放?

    有谁知道为什么 iPad 缩放 你知道 你用两根手指放大文本 屏幕 在某些网站上不起作用 例如 脸书网 c3 arc nasa gov nex 我正在工作的网站 谷歌搜索没有显示任何内容 这让我认为这不是一个常见问题 预先感谢您的任何见解
  • 如何在Android Studio中安装android 6.0.1模拟器?

    我在我的 Android 模拟器上遇到这个问题E Surface getSlotFromBufferLocked 未知缓冲区 0xab7519c0 https stackoverflow com questions 33046375 e s
  • 将文本中的所有 URL 替换为 PHP 中的可点击链接[重复]

    这个问题在这里已经有答案了 我有一个用 PHP 编写的 Web 应用程序 我想找到用户评论中的所有 URL 并将它们更改为可点击的链接 我搜索了很多网站和页面 找到了以下解决方案 不幸的是我没有再次找到它的参考链接 感谢其作者 该代码可以完
  • 本机反应:“order”不是有效的样式属性

    顺序是 Flex 中一个有用的属性 我在互联网上搜索这个 概括 CSS order 属性指定用于在 Flex 容器中布置 Flex 项目的顺序 元素按顺序值的升序排列 具有相同 order 值的元素按照它们在源代码中出现的顺序排列
  • Angular cli - 在“deployUrl”选项被弃用后在 webpack 中设置“publicPath”

    我希望在这里得到更多答案 开放问题角度 cli https github com angular angular cli issues 22113以及 从角度 13 开始 它说deployUrl正在被弃用 在我们的项目中 我们定义deplo
  • 使用 C# 截取任何外部应用程序的屏幕截图

    我们有一个 C WPF 应用程序 我们想要在其中截取我们启动的任意应用程序的屏幕截图 即 我们可以引用我们启动的进程 应用程序可能已最小化或位于其他窗口后面 但我们仍然只需要单个应用程序的图像 而不是重叠像素 我知道使用 BitBlt 或的
  • 如何将动态格式字符串与格式一起使用!宏?

    我想使用format 宏与String作为第一个参数 但因为宏需要字符串文字 所以我无法传递任何与它不同的内容 我想这样做是为了将字符串动态添加到当前字符串中 以便在视图引擎中使用 如果有更好的方法 我愿意接受建议 let test Str
  • Android 3.1 USB 主机 - BroadcastReceiver 未收到 USB_DEVICE_ATTACHED

    我经历过USB 主机的描述和示例位于developer android com http developer android com guide topics usb host html检测连接和分离的 USB 设备 如果我在清单文件中使用
  • React 状态总是从 Fabricjs 的回调中返回先前(或初始)状态

    下面的代码是我的最小问题重现组件 它初始化织物画布 并处理 模式 状态 模式状态决定画布是否可以编辑 并且一个简单的按钮控制该状态 问题是 即使mode setMode工作正常 意思是 单击按钮后组件分析器显示正确的状态 按钮内的文本也显示