一直在使用新的钩子 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;
起初我认为这是热重新加载的问题,但删除后我仍然收到此错误:
未捕获的错误:只能在函数组件的主体内调用挂钩。
我只有在使用导入和导出时才会遇到这个问题。如果我复制相同的自定义钩子函数并将其粘贴到我的组件上方,它可以正常工作。
我假设我在做一些愚蠢的事情或者没有足够好地阅读文档。
干杯