@HitGirl

Как передать ref в хук?

Здравствуйте!
Пример ниже не работает, так как в useHover передаётся null, вместо ссылки на элемент. Как это можно исправить?
function useEventListener(event: string, callback: (e: any) => void, element: EventTarget = document ,useCapture = false) {
    const callbackRef = useRef(callback)

    callbackRef.current = callback
    useEffect(() => {
        callbackRef.current = callback
    }, [callback])

    useEffect(() => {
        if (element == null) return
        const handler = (e:any) => callbackRef.current(e)
        element.addEventListener(event, handler,useCapture)
        return () => {
            element.removeEventListener(event, handler)
        };
    }, [event, element])
}

function useHover(ref:MutableRefObject<any>) {
    const [hovered, setHovered] = useState(false)

    console.log(ref.current)
    useEventListener("mouseover", () => setHovered(true), ref.current)
    useEventListener("mouseout", () => setHovered(false), ref.current)

    return hovered
}

const UseHover:FC = ()=>{
    const elementRef = createRef<HTMLDivElement>()
    const hovered = useHover(elementRef)
    const [count, setCount] = useState(0)

    return (
        <>
        <div
            ref={elementRef}
            style={{
                backgroundColor: hovered ? "blue" : "red",
                width: "100px",
                height: "100px",
                position: "absolute",
                top: "calc(50% - 50px)",
                left: "calc(50% - 50px)",
            }}
        />
        <button onClick={()=>setCount(prev=>prev+1)}>{count}</button></>
    )
}

export default UseHover;
  • Вопрос задан
  • 150 просмотров
Пригласить эксперта
Ответы на вопрос 2
Alexandroppolus
@Alexandroppolus
кодир
Ты за каким-то хреном смотришь ref.current на этапе рендера. Понятно, что там будет нулл. Актуальное значение будет только к моменту useEffect или useLayoutEffect.

Кстати, в useEventListener тоже какая-то дичь. Нафига этот прикол с callbackRef, непонятно.
Ответ написан
@HitGirl Автор вопроса
function useHover(ref:MutableRefObject<any>) {
    const [hovered, setHovered] = useState(false)


    useEffect(()=>{
        if (ref.current == null) return
        const handlerOver = () => setHovered(true)
        const handlerOut = () => setHovered(false)
        ref.current.addEventListener("pointerover", handlerOver)
        ref.current.addEventListener("pointerout", handlerOut)
        return () => {
            ref.current.removeEventListener("pointerover", handlerOver)
            ref.current.removeEventListener("pointerout", handlerOut)
        };

    },[ref.current])

    return hovered
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы