Ошибка импорта пользовательских хуков в React 16.7.0-alpha

Поигрался с новым хуком RFC в React и не могу заставить свой собственный хук работать должным образом. Не уверен, что то, что происходит, на моей стороне, или это ошибка самой React alpha.

Я пытался создать крючок за пределами клика. Я смог заставить его работать с этим кодом.

./dropdown_builtin_hooks

const DropDownWrapper = React.memo(props => {
  const { user, className } = props;
  const ref = useRef(null);
  const [active, setActive] = useState(false);

  useEffect(() => {
    const handleDOMClick = event => {
      console.log(event.target);
      if (active && !!ref && !(event.target === ref.current || ref.current.contains(event.target))) {
        console.log("Clicked outside of wrapped component");
        setActive(false);
      }
    };
    window.addEventListener("click", handleDOMClick);
    return () => {
      window.removeEventListener("click", handleDOMClick);
    };
  });

  const handleDropDown = (): void => {
    setActive(true);
  };

  return (
    <div ref={ref} className={className} >
      <Toggler onClick={handleDropDown}>
        {active ? (
          <StyledDropUpArrow height="1.5em" filled={false} />
        ) : (
          <StyledDropDownArrow height="1.5em" filled={false} />
        )}
      </Toggler>
      {active && (
        <DropDown/>
      )}
    </div>
  );
});

export default DropDownWrapper;

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

./hooks

export function useClickedOutside<RefType = any>(
  initialState: boolean = false,
): [React.RefObject<RefType>, boolean, Function] {
  const ref = useRef(null);
  const [active, setActive] = useState(initialState);

  useEffect(() => {
    const handleDOMClick = event => {
      console.log(event.target);
      if (active && !!ref && !(event.target === ref.current || ref.current.contains(event.target))) {
        console.log("Clicked outside of wrapped component");
        setActive(false);
      }
    };
    window.addEventListener("click", handleDOMClick);
    return () => {
      window.removeEventListener("click", handleDOMClick);
    };
  });
  return [ref, active, setActive];
}

./dropdown_custom_hook

const DropDownWrapper = React.memo(props => {
  const { user, className } = props;
  const [ref, active, setActive] = useClickedOutside(false);

  const handleDropDown = (): void => {
    setActive(true);
  };

  return (
    <div ref={ref} className={className} >
      <Toggler onClick={handleDropDown}>
        {active ? (
          <StyledDropUpArrow height="1.5em" filled={false} />
        ) : (
          <StyledDropDownArrow height="1.5em" filled={false} />
        )}
      </Toggler>
      {active && (
        <DropDown/>
      )}
    </div>
  );
});

export default DropDownWrapper;

Сначала я подумал, что это проблема с горячей перезагрузкой, но после ее удаления я все еще получаю эту ошибку:

Неперехваченная ошибка: ловушки можно вызывать только внутри тела функционального компонента.

У меня эта проблема возникает только тогда, когда я использую импорт и экспорт. Если я скопирую ту же настраиваемую функцию перехвата и вставлю ее над своим компонентом, она будет работать правильно.

Я предполагаю, что делаю что-то глупое или недостаточно хорошо прочитал документацию.

Ваше здоровье


person Zach    schedule 29.10.2018    source источник
comment
Это была моя первая проблема, но, как я уже сказал, я уже удалил ее и заставил работать без специального крючка. Я также использовал псевдоним для импорта хука, но удаление его, похоже, тоже не решило проблему.   -  person Zach    schedule 30.10.2018
comment
да, извините, пропустил, что вы уже это проверили   -  person skyboyer    schedule 30.10.2018
comment
поэтому для импорта / экспорта вы используете useEffect, useRef прямо в своей функции, но вне функционального компонента. Я считаю, что вы просто не можете этого сделать. Поэтому вам нужно перекомпоновать повторно используемую часть по-другому, чтобы она содержала только бизнес-логику, но не взаимодействие между разными хуками.   -  person skyboyer    schedule 30.10.2018
comment
Просто к сведению всех, кто здесь окажется, вам нужно обновить и React, и ReactDOM до @next, чтобы хуки работали. Если вы этого не сделаете, реакция выдаст указанную выше ошибку. Я знаю, потому что у меня только что была эта проблема, и это было моим решением.   -  person Tony    schedule 30.10.2018
comment
Ха-ха, я чуть не почувствовал себя действительно глупым на секунду, к счастью, и react, и react dom - правильная версия. Вчера вечером, когда я вернулся из офиса, поиграл еще, и этот код работал в новом проекте React. Я полагаю, что есть проблема с одной из моих зависимостей проекта.   -  person Zach    schedule 30.10.2018
comment
Что ж, я сейчас в растерянности. Я считаю, что есть проблема с styled-components и typescript, но я не могу воспроизвести эту ошибку, кроме как в моей кодовой базе. Я использовал недавно выпущенный typescript create-react-app и добавил styled-components, но он там работает. Я думаю, что в моем babelrc или webpack configs должно быть что-то, что вызывает проблему. Моя интуиция подсказывает мне, что это связано с этой проблемой или другой упомянутой проблемой, но я не могу воспроизвести ошибку в песочнице, чтобы сделать меня проблемой ????   -  person Zach    schedule 30.10.2018
comment
Вроде работает нормально. См. Песочницу: codeandbox.io/s/y7k4o2q79x   -  person Yangshun Tay    schedule 06.11.2018