Как сказать компоненту React изменить его состояние, когда событие запускается из сторонней библиотеки? - PullRequest
1 голос
/ 17 октября 2019

Я использую createjs для создания холста, и на этом холсте есть событие двойного щелчка, теперь я хочу сообщить компоненту React, когда событие инициируется, и установить состояние переменной, определенной в пользовательскомфункция. например, я хочу установить значение 'pose.position' в пользовательской функции.

мой компонент реакции:

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;

Проблема в том, что значение в компоненте устанавливается только один раз, и функция журнала в handleEvent выводит значение NULL, значение не будет обновляться. Как я могу уведомить React, что значение изменилось? Должен ли я создать еще один useEffect(()=>{}, [value])?

ИЛИ

Можно ли отправить действие в this.rootObject.addEventListener, чтобы я мог уведомить о реакции на повторную визуализацию некоторых компонентов? Могу ли я использовать избыточность в функции без реакции?

1 Ответ

1 голос
/ 17 октября 2019

Из того, что я вижу, есть 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 для предотвращения повторного рендеринга.

...