当 none 个元素可见时,IntersectionObserverAPI Return 为默认状态
IntersectionObserverAPI Return to default state when none of the elements are visible
我正在使用 React Hook 来检测元素何时在视口中可见。在那之前,一切正常,但我需要 'reset' 隐藏所有内容时的状态(比如到达页脚或页眉)。
这是我的钩子:
import { useState, useEffect, useRef } from 'react'
const useIntersect = (ref) => {
const [isOnScreen, setIsOnScreen] = useState(false)
const observerRef = useRef(null)
useEffect(() => {
observerRef.current = new IntersectionObserver(([entry]) => {
setIsOnScreen(entry.isIntersecting)
})
}, [])
useEffect(() => {
observerRef.current.observe(ref.current)
return () => observerRef.current.disconnect()
}, [ref])
return isOnScreen
}
export default useIntersect
这是我正在更新的状态:
const elementRef = useRef(null)
const[state, setState] = useState('nothing is visible')
const onScreen = useIntersect(elementRef)
useEffect(() => {
return onScreen ? setState('an item is visible') : null
})
return (
<Item ref={elementRef}>
...
</Item>
)
当所有元素都离开视口时(当不满足 onScreen 条件时),我需要能够对某些东西(比如字符串)说 setState('...')
,但即使我到达页脚时什么都不可见,它保留内存中的最后一项。
我尝试了很多方法,但我想不出出路:(
感谢您的帮助!
我认为问题在于您如何将 elementRef 传递给挂钩。
useIntersect useEffect 不会在 elementRef 改变时执行。
import { useState, useEffect, useRef } from "react";
const useIntersect = () => {
const ref = useRef(null);
const [isOnScreen, setIsOnScreen] = useState(false);
useEffect(() => {
if (!ref) {
const observer = new IntersectionObserver(([entry]) =>
setIsOnScreen(entry.isIntersecting)
);
observer.observe(ref.current);
return () => observer.disconnect();
}
}, [ref]);
return [isOnScreen, ref];
};
export default useIntersect;
// -----------------------------Component-------------------------------
const [state, setState] = useState("nothing is visible");
const [onScreen, elementRef] = useIntersect();
useEffect(() => {
return onScreen ? setState("an item is visible") : null;
});
return <Item ref={elementRef}></Item>;
你的钩子实现看起来不错。您可能需要重新检查 Item
组件的高度。
检查此代码沙箱与您的挂钩实现是否正常工作
: https://codesandbox.io/s/elegant-wood-ruks2?file=/src/App.js
我相信你的 useIntersect
钩子应该为第二个 useEffect
添加对 ref.current
而不是 ref
的依赖
所以
useEffect(() => {
observerRef.current.observe(ref.current)
return () => observerRef.current.disconnect()
}, [ref.current]);
然后在组件中使用时做
useEffect(() => {
return onScreen ? setState('an item is visible') : setState('nothing is visible');
}, [onScreen])
你应该添加对 onScreen
的依赖,这样它只会在 onScreen
发生变化时更新,最后你应该为 onScreen
的场景调用 setState
] 与您想要的值不符。
我正在使用 React Hook 来检测元素何时在视口中可见。在那之前,一切正常,但我需要 'reset' 隐藏所有内容时的状态(比如到达页脚或页眉)。
这是我的钩子:
import { useState, useEffect, useRef } from 'react'
const useIntersect = (ref) => {
const [isOnScreen, setIsOnScreen] = useState(false)
const observerRef = useRef(null)
useEffect(() => {
observerRef.current = new IntersectionObserver(([entry]) => {
setIsOnScreen(entry.isIntersecting)
})
}, [])
useEffect(() => {
observerRef.current.observe(ref.current)
return () => observerRef.current.disconnect()
}, [ref])
return isOnScreen
}
export default useIntersect
这是我正在更新的状态:
const elementRef = useRef(null)
const[state, setState] = useState('nothing is visible')
const onScreen = useIntersect(elementRef)
useEffect(() => {
return onScreen ? setState('an item is visible') : null
})
return (
<Item ref={elementRef}>
...
</Item>
)
当所有元素都离开视口时(当不满足 onScreen 条件时),我需要能够对某些东西(比如字符串)说 setState('...')
,但即使我到达页脚时什么都不可见,它保留内存中的最后一项。
我尝试了很多方法,但我想不出出路:(
感谢您的帮助!
我认为问题在于您如何将 elementRef 传递给挂钩。
useIntersect useEffect 不会在 elementRef 改变时执行。
import { useState, useEffect, useRef } from "react";
const useIntersect = () => {
const ref = useRef(null);
const [isOnScreen, setIsOnScreen] = useState(false);
useEffect(() => {
if (!ref) {
const observer = new IntersectionObserver(([entry]) =>
setIsOnScreen(entry.isIntersecting)
);
observer.observe(ref.current);
return () => observer.disconnect();
}
}, [ref]);
return [isOnScreen, ref];
};
export default useIntersect;
// -----------------------------Component-------------------------------
const [state, setState] = useState("nothing is visible");
const [onScreen, elementRef] = useIntersect();
useEffect(() => {
return onScreen ? setState("an item is visible") : null;
});
return <Item ref={elementRef}></Item>;
你的钩子实现看起来不错。您可能需要重新检查 Item
组件的高度。
检查此代码沙箱与您的挂钩实现是否正常工作
: https://codesandbox.io/s/elegant-wood-ruks2?file=/src/App.js
我相信你的 useIntersect
钩子应该为第二个 useEffect
ref.current
而不是 ref
的依赖
所以
useEffect(() => {
observerRef.current.observe(ref.current)
return () => observerRef.current.disconnect()
}, [ref.current]);
然后在组件中使用时做
useEffect(() => {
return onScreen ? setState('an item is visible') : setState('nothing is visible');
}, [onScreen])
你应该添加对 onScreen
的依赖,这样它只会在 onScreen
发生变化时更新,最后你应该为 onScreen
的场景调用 setState
] 与您想要的值不符。