Ref 问题和在 useEffect 后调用自定义挂钩
Ref issue and Calling custom hook after useEffect
我正在使用自定义挂钩来检测外部点击
const useClickOutside = (nodeElement, handler) => {
function handleClickOutside(event) {
if (nodeElement && !nodeElement.contains(event.target)) {
handler();
}
}
useEffect(() => {
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
}
我是这样称呼它的
const Modal = ({ ... }) => {
const modalRef = useRef(null);
console.log(modalRef.current) // null
useEffect(() => {
console.log(modalRef.current) // work fine here and display the dom element
}, [])
// here the hooks it is called with modalRef.current as null
useClickOutside(modalRef.current, () => {
dispatch(hideModal());
});
return (
<div className="pop-container">
<div className="pop-dialog" ref={modalRef}>
...
</div>
</div>
)
}
问题是我的自定义挂钩 useClickOutside
被调用 modalRef.current
作为 null
正如您在 useEffet
挂钩中看到的那样,modalRef.current
值是正确的
但是我不能在 useEffet
那里调用我的自定义挂钩,否则我会得到 Uncaught Invariant Violation: Hooks can only be called inside the body of a function component
那么如何解决这个问题?
如果您只传递 ref,而不是传递 ref.current,您的代码将起作用,因为 ref.current 将在分配 ref 时在其引用处发生突变
const useClickOutside = (nodeElement, handler) => {
function handleClickOutside(event) {
if (nodeElement.current && !nodeElement.current.contains(event.target)) {
handler();
}
}
useEffect(() => {
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
}
和模态
const Modal = ({ ... }) => {
const modalRef = useRef(null);
// here the hooks it is called with modalRef.current as null
useClickOutside(modalRef, () => {
dispatch(hideModal());
});
return (
<div className="pop-container">
<div className="pop-dialog" ref={modalRef}>
...
</div>
</div>
)
}
我正在使用自定义挂钩来检测外部点击
const useClickOutside = (nodeElement, handler) => {
function handleClickOutside(event) {
if (nodeElement && !nodeElement.contains(event.target)) {
handler();
}
}
useEffect(() => {
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
}
我是这样称呼它的
const Modal = ({ ... }) => {
const modalRef = useRef(null);
console.log(modalRef.current) // null
useEffect(() => {
console.log(modalRef.current) // work fine here and display the dom element
}, [])
// here the hooks it is called with modalRef.current as null
useClickOutside(modalRef.current, () => {
dispatch(hideModal());
});
return (
<div className="pop-container">
<div className="pop-dialog" ref={modalRef}>
...
</div>
</div>
)
}
问题是我的自定义挂钩 useClickOutside
被调用 modalRef.current
作为 null
正如您在 useEffet
挂钩中看到的那样,modalRef.current
值是正确的
但是我不能在 useEffet
那里调用我的自定义挂钩,否则我会得到 Uncaught Invariant Violation: Hooks can only be called inside the body of a function component
那么如何解决这个问题?
如果您只传递 ref,而不是传递 ref.current,您的代码将起作用,因为 ref.current 将在分配 ref 时在其引用处发生突变
const useClickOutside = (nodeElement, handler) => {
function handleClickOutside(event) {
if (nodeElement.current && !nodeElement.current.contains(event.target)) {
handler();
}
}
useEffect(() => {
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
}
和模态
const Modal = ({ ... }) => {
const modalRef = useRef(null);
// here the hooks it is called with modalRef.current as null
useClickOutside(modalRef, () => {
dispatch(hideModal());
});
return (
<div className="pop-container">
<div className="pop-dialog" ref={modalRef}>
...
</div>
</div>
)
}