javascript - 当第三方库触发事件时,我如何告诉 React 组件更改其状态?

标签 javascript reactjs createjs

我正在使用 createjs 创建一个 Canvas ,这个 Canvas 中有一个双击事件,现在我想在事件被触发时告诉一个 React 组件,并将状态设置为一个变量在自定义函数中定义的。例如,我想将值设置为自定义函数中的“pose.position”。

我的 react 组件:

const [value, setValue] = useState(null);
const handleEvent = event => {
   console.log(value);
};
useEffect(() => {
const ros = new ROSLIB.Ros({
   url
});
const viewer = new ROS2D.Viewer({
   divID,
   width,
   height
});
const nav = NAV2D.OccupancyGridClientNav({
   ros,
   rootObject: viewer.scene,
   viewer,
   serverName,
   continuous
});
setValue(nav.position);

const canvas = divEl.current.children[0];

canvas.addEventListener("dblclick", handleEvent, false);

return () => {
    canvas.removeEventListener("dblclick", handleEvnet);
};
}, []);

return <div id={divID} ref={divEl} />;

和自定义函数:

this.rootObject.addEventListener("dblclick", function(event) {
  // convert to ROS coordinates
  const coords = stage.globalToRos(event.stageX, event.stageY);
  const pose = new ROSLIB.Pose({
     position: new ROSLIB.Vector3(coords)
  });
  // send the goal
  sendGoal(pose);
  that.position = pose.position;
  // that.mouseClick = true;
  console.log("clicked");
  });
  //I do not know how my React component can get this value, so I just return
  return this.position;

问题是component中的value只设置了一次,handleEvent中的log函数输出null,value不会更新。如何通知React value改变了?我应该创建另一个 useEffect(()=>{}, [value]) 吗?

我能否在 this.rootObject.addEventListener 中分派(dispatch)一个 Action ,以便通知 React 重新渲染某些组件?我可以在非 react 函数中使用 redux 吗?

最佳答案

据我所知,有 2 个选项可以实现此功能:
1)将计算position的部分放到React组件中:

const [value, setValue] = useState(null);
const handleEvent = event => {
  // convert to ROS coordinates
  const coords = stage.globalToRos(event.stageX, event.stageY);
  const pose = new ROSLIB.Pose({
    position: new ROSLIB.Vector3(coords)
  });
  setValue(pose.position);
};

2) 引入一个额外的事件并在组件中监听它。这样您的自定义函数将如下所示:

this.rootObject.addEventListener("dblclick", function(event) {
  // convert to ROS coordinates
  const coords = stage.globalToRos(event.stageX, event.stageY);
  const pose = new ROSLIB.Pose({
    position: new ROSLIB.Vector3(coords)
  });
  // send the goal
  sendGoal(pose);
  this.dispatchEvent(new CustomEvent('newposition', { detail: pose.position }));
}

然后在你的 React 组件中添加额外的一行:

canvas.addEventListener("newposition", (e) => setValue(e.detail), false);

在这两种情况下,您都需要添加 value 作为 useEffect 的第二个参数以防止重新呈现。

关于javascript - 当第三方库触发事件时,我如何告诉 React 组件更改其状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58427983/

相关文章:

javascript - 这些代码中的 `{}` 和 `()` 有什么区别?

javascript - 使用 drawImage 将加载的图像淡化到 Canvas 中

javascript - 在 react.js 中有什么方法可以禁用所有子事件

javascript - 如何使用 easeljs-0.8.0.js 画线?(createJs)

javascript - 扩展 "class"并通过模块导出

javascript - PHP:javascript警报,带有来自sql查询的值,进入IF条件

javascript - ng-class 仅适用于 ng-repeat angularjs 中的当前范围

javascript - 如何使用 Enzyme/Jest 测试 ComponentWillMount 中的逻辑

javascript - 竞争条件 : Trying to play a video before it loads React

javascript - 遇到经典的模糊问题但没有找到可行的解决方案