Использование useRef для фокусировки элемента, перенос класса на хуки? - PullRequest
0 голосов
/ 30 марта 2020

Кто-нибудь знает, как правильный подход для передачи ссылок обратного вызова с использованием перехватчиков реагирования. Я пытаюсь преобразовать модал, встроенный в компонент класса, в компонент ловушки, но я не уверен, как правильно это сделать.

  onOpen = () => {
   this.setState({ isOpen: true }, () => {
    // Ref for the button
    this.closeButtonNode.focus();
   });
   this.toggleScrollLock();
  };

И вот как я передаю ссылка в коде

     <ModalContent
      buttonRef={(n) => {
        this.closeButtonNode = n;
      }}
      {// More props...}
    />

И у компонента модального содержимого есть buttonRef, как это

         <button
          type="button"
          className="close"
          aria-labelledby="close-modal"
          onClick={onClose}
          ref={buttonRef}
        >
          <span aria-hidden="true">×</span>
        </button>

Так что, когда модальное всплывающее окно, я смог сфокусироваться при закрытии моей кнопки, с хуками единственный способ, которым мне удалось воспроизвести поведение, - это добавить хук useEffect, который прослушивает состояние isOpen, например:

useEffect(() => {
 if (isOpen) closeButtonNode.current.focus();
}, [isOpen]);

const onOpen = () => {
 setIsOpen(true);
 toggleScrollLock();
};

И вот как я передаю пропу

  const closeButtonNode = useRef(null);
  return (
  <ModalContent
    buttonRef={closeButtonNode}
    {// More props...}
  />
  )

И я просто использую его как обычную ссылку, не передавая функцию обратного вызова, это работает, но мне интересно, почему это работает так и почему я не могу установить фокус на функцию onOpen, как компонент, основанный на классе.

Это песочница, если вы хотите проверить полный код. https://codesandbox.io/s/hooks-modal-vs-class-modal-bdjf0

1 Ответ

0 голосов
/ 30 марта 2020

Почему я не могу установить фокус на функцию onOpen, как компонент на основе классов

Потому что, когда вызывается функция onOpen, open все еще переключается false, и это будет обновляться после того, как модал уже открыт. Обратите внимание, что useState не имеет второго аргумента (обратного вызова), такого как setState в компоненте на основе классов, как вы сделали для установки фокуса. Вот почему вам нужно было использовать useEffect.

. Вы можете проверить это, установив задержку с помощью setTimeout после того, как для open установлено значение true, например:

const onOpen = () => {
  setIsOpen(true);
  setTimeout(() => closeButtonNode.current.focus())
};

Хотя, Ваш подход с использованием useEffect может быть лучшим вариантом.

codeSandbox пример.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...