首页 > 解决方案 > 在 React 16.7.0-alpha 中导入自定义钩子时出错

问题描述

一直在使用新的钩子 RFC 进行反应,但无法让我的自定义钩子正常工作。不知道到底发生了什么,还是 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;

但是,当我尝试将其包装在自定义挂钩中时,我可以重用并将其导入到我的组件中。像这样的东西...

./钩子

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;

起初我认为这是热重新加载的问题,但删除后我仍然收到此错误:

未捕获的错误:只能在函数组件的主体内调用挂钩。

我只有在使用导入和导出时才会遇到这个问题。如果我复制相同的自定义钩子函数并将其粘贴到我的组件上方,它可以正常工作。

我假设我在做一些愚蠢的事情或者没有足够好地阅读文档。

干杯

标签: reactjstypescriptreact-hooks

解决方案


推荐阅读