当前位置: 首页 > 知识库问答 >
问题:

React钩子不返回库事件回调函数中更新的状态值(FabricJS)

郎曜文
2023-03-14

我没有在FabricJS事件中获得更新的状态值,如object:modified、mouse:up等。。。但我可以在回调函数中设置状态值。

当我试图获取状态值时,它返回的是初始值,而不是更新后的值。

例子:

const [count, setCount] = useState(0);

初始值为0。我使用setCount将值更新为1。每当我试图在回调函数中获取“count”时,它都返回0或初始值。

编辑:

我试图实现的是,每当对象修改(对于撤销,重做操作)时,我试图保存FabricJS对象。每当对象发生变化时,FabricJS都会触发事件并调用组件中的函数。但是我没有得到州的价值。

代码:

function MyFunction()
{
   const [canvasObj, setCanvasObj] = useState({});
   const [state, setCanvasState] = useState('');
   const [undo, setUndo] = useState([]);

   useEffect(() => {

      if(Object.keys(canvasObj).length == 0) {
         var _canvas = new fabric.Canvas('canvas', {
            preserveObjectStacking: true,
         });

         setCanvasObj(_canvas);

         _canvas.on("object:modified", saveState);
      }
   });

   function saveState() {
       console.log(canvasObj); // Returns null even though object initialised
       if (state) { // state value returns null. Due to this, I can't get the existing data and push the current state
          let newState = undo;
          newState.push(state);
          setUndo(newState);
       }
       const tmpState = JSON.stringify(canvasObj);
       setCanvasState(tmpState);
   }
}

共有1个答案

谢学名
2023-03-14

下面是如何在react组件中保存画布状态的一般示例。您需要一个单独的变量来跟踪画布历史记录的更改:

js prettyprint-override">import React, { useRef, useEffect, useCallback, useState } from "react";
import { fabric } from "fabric";

export default function App() {
  const canvasRef = useRef();
  const [canvas, setCanvas] = useState();
  // Array of objects, that represents canvas state history
  const [canvasHistory, setCanvasHistory] = useState([initialState]);
  const [canvasState, setCanvasState] = useState(initialState);

  const onObjectModified = useCallback(
    e => {
      const newCanvasState = e.target.canvas.toJSON();
      setCanvasState(newCanvasState);
      // Limit history depth
      setCanvasHistory(history => [...history, newCanvasState].slice(-4));
    },
    [setCanvasState, setCanvasHistory]
  );

  useEffect(() => {
    const canvas = new fabric.Canvas(canvasRef.current);
    canvas.loadFromJSON(initialState);

    canvas.on("object:modified", onObjectModified);
    setCanvas(canvas);

    // Don't forget to destroy canvas and remove event listeners on component unmount
    return () => canvas.dispose();
  }, [canvasRef, onObjectModified, setCanvas]);

  const moveHistory = useCallback(
    step => {
      const currentStateIndex = canvasHistory.indexOf(canvasState);
      const prevState = canvasHistory[currentStateIndex + step];
      canvas.loadFromJSON(prevState);
      setCanvasState(prevState);
    },
    [canvas, canvasState, canvasHistory, setCanvasState]
  );

  const onUndo = useCallback(() => moveHistory(-1), [moveHistory]);

  const onRedo = useCallback(() => moveHistory(1), [moveHistory]);

  return (
    <div>
      <button onClick={onUndo} disabled={canvasHistory[0] === canvasState}>
        Undo
      </button>
      <button
        onClick={onRedo}
        disabled={canvasHistory[canvasHistory.length - 1] === canvasState}
      >
        Redo
      </button>
      <canvas ref={canvasRef} width="300" height="300" />
    </div>
  );
}

另外,我在这里做了一个简单的工作示例

 类似资料:
  • 我有一个函数反应组件,它有一个从10000开始到0的计数器。 我正在组件安装期间使用useEffect挂钩设置setInterval回调。然后,回调更新计数器状态。 但是不知道为什么,值从来没有减少过。每次回调运行为10000。 (我正在使用react 功能组件如下所示: 这里是codesandbox的链接:链接

  • 我正在构建一个制表符视图,我不明白为什么useState钩子没有更新我的状态。我肯定这是件容易的事,但我在这里已经被难住了一段时间... 我可以看到onPress函数已启动,如果我注销,则item.label是正确的。但是,即使我硬编码参数,setState也不会更改。

  • 问题内容: 我正在尝试学习如何实现React表单(ES6语法)并将每个字段的onChange事件传递到负责更新状态的控制器父组件。这对于标准html元素来说效果很好,但是我正在尝试对日期字段使用预先罐装的Datepicker(https://www.npmjs.com/package/react- bootstrap-date-picker ),并且无法随时通过事件以相同的方式备份到父级。有没有简

  • 问题内容: 我正在使用Postgresql 8.3,并具有以下简单功能,该功能会将a返回 给客户端 现在,我可以使用以下SQL命令来调用此函数并操纵返回的游标,但是游标名称是由PostgreSQL自动生成的 此外,如38.7.3.5中所述,显式地将游标名称声明为函数的输入参数 。返回游标。我可以声明自己的游标名称并使用此游标名称来操纵返回的游标,而不是为我自动生成的Postgresql吗?如果不是

  • 我正在学习React钩子,这意味着我将不得不从类转移到函数组件。以前,在类中,我可以拥有与状态无关的类变量,我可以在不重新呈现组件的情况下更新这些变量。现在我试图用钩子重新创建一个组件作为函数组件,我遇到了这样一个问题:我不能(就我所知)为该函数创建变量,因此存储数据的唯一方法是通过钩子。然而,这意味着每当该状态更新时,我的组件将重新呈现。 我已经在下面的示例中说明了这一点,我试图将类组件重新创建

  • 我有一个类组件,它返回使用Redux存储完全填充的状态: 但是,当我将上面的类组件切换到下面的功能组件,以便可以在代码中使用ReactJS钩子时,状态始终为空。