引用问题和useEffect后调用自定义钩子

时间:2019-03-26 23:46:58

标签: reactjs react-hooks

我正在使用自定义挂钩来检测外部点击

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.currentnull称为useEffet

正如您在modalRef.current钩中看到的那样,useEffet的值是正确的

但是我无法在Uncaught Invariant Violation: Hooks can only be called inside the body of a function component中调用自定义钩子,否则我将得到showModal ( {commit}, modalPayload ) { let delay; if(modalPayload.delay == undefined){ delay = 3000; } else{ delay = modalPayload.delay } commit('SHOW_MODAL', modalPayload); setTimeout(function(){ commit('HIDE_MODAL'); }, delay); },

那么如何解决这个问题呢?

1 个答案:

答案 0 :(得分:1)

如果您仅传递ref,则无需传递ref.current,而是可以使用代码,因为分配ref时,ref.current将在其引用处发生变异

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>
    )
}

Working demo