Как смонтировать / размонтировать компонент в React нажатием клавиши? - PullRequest
0 голосов
/ 12 июля 2020

Я делаю приложение, которое отображает 3D-объекты при нажатии на клавиатуру. Я бы хотел, чтобы эти объекты исчезли через 2-3 секунды или когда анимация закончится.

Это компонент, который обрабатывает нажатую клавишу logi c:

const Selector = () => {
  const [selector, setSelector] = useState(null);
  useEffect(() => {
    function setupKeyLogger() {
      document.onkeydown = function (e) {
        console.log(e);
        switch (e.keyCode) {
          case 65:
            setSelector('SpinningCube');
            break;
          case 83:
            setSelector('SmallCube');
            break;
          default:
            break;
        }
      };
    }
    setupKeyLogger();
  });
  switch (selector) {
    case 'SpinningCube':
      return (
        <>
          <SpinningCube />
        </>
      );
    case 'SmallCube':
      return (
        <>
          <SmallCube />
        </>
      );
    default:
      return <></>;
  }
};

Прямо сейчас он переключается между двумя объектами <SpinningCube /> и <SmallCube />, когда я нажимаю две разные клавиши. Однако, если я спамлю ключ, он отображает компонент только при первом нажатии клавиши. Я хочу, чтобы он повторно отображал и перезапускал анимацию компонента каждый раз, когда я нажимаю клавишу, даже если она повторяется снова и снова. Я предполагаю, что мне нужен способ размонтировать, а затем повторно установить компонент при каждом нажатии клавиши?

Я использую Three и React Spring для обработки своих анимаций.

1 Ответ

1 голос
/ 13 июля 2020

Компоненты будут повторно визуализироваться при изменении свойств или состояния. Когда вы спамите кнопку, то состояние устанавливается, но не изменяется, поэтому ничего не происходит. Итак, вам нужен еще один параметр, который нужно переключать при каждом нажатии и передавать дочерним элементам (заставляя их выполнять повторную визуализацию).

const Selector = () => {
  const [selector, setSelector] = useState(null);
  const [forceRender, setForceRender] = useState(0);
  const forceAnimation = (selected) => {
    setSelector(selected);
    setForceRender(++forceRender);
  };

  useEffect(() => {
    function setupKeyLogger() {
      document.onkeydown = function (e) {
        console.log(e);
        switch (e.keyCode) {
          case 65:
            forceAnimation('SpinningCube');
            break;
          case 83:
            forceAnimation('SmallCube');
            break;
          default:
            break;
        }
      };
    }
    setupKeyLogger();
  });

  switch (selector) {
    case 'SpinningCube':
      return (
        <key={forceRender}> // if this doesn't work, I'd try passing it to a React.Fragment or div instead
          <SpinningCube />
        </>
      );
    case 'SmallCube':
      return (
        <key={forceRender}>
          <SmallCube />
        </>
      );
    default:
      return <></>;
  }
};
...