IntersectionObserver 没有在 React 中更新
IntersectionObserver not updating in React
以下代码将在元素通过滚动进入或离开视口时立即触发状态更改
const dialog = useRef(),
[visible, set] = useState(false)
useEffect(() => {
const observer = new IntersectionObserver((e) => {
set(e[0].isIntersecting ? true : false)
}, {root: null, rootMargin: '0px', threshold: 0})
observer.observe(dialog.current)
return () => observer.disconnect()
}, [dialog.current])
return <div ref={dialog}>my dialog</div>
但如果我尝试这样的事情
const observer = new IntersectionObserver((e) => {
set(e[0].boundingClientRect.y <= 0 ? true : false)
}, {root: null, rootMargin: '0px', threshold: 0})
仅当触发重新渲染时状态才会更新,而我希望它在我滚动视口时根据观察到的元素的 boundingClientRect.y
值触发。
我发现完成这项工作的唯一方法是在 useEffect
中使用 window.onscroll
事件并将观察者放在其中,但它对我来说不太好。有没有比使用 window.onscroll
不同(更好)的方法?
这是因为在 useEffect
挂钩中实例化 IntersectionObserver
时 DOM 内容未完全加载。
不使用 window.onscroll
的解决方法是 运行 组件中的钩子并将你的 setter 作为道具传递。
像这样
function MyObserver({ selector, callback }){
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => callback(entries),
{ root: null, rootMargin: '0px', threshold: 0 });
const element = document.querySelector(selector);
observer.observe(element);
return () => {
observer.disconnect();
};
}, []);
return null;
}
function Main() {
[visible, set] = useState(false);
return <>
<div className="myDialog">my dialog</div>
<MyObserver selector=".myDialog"
callback={ (e) => { set(e[0].isIntersecting ? true : false); } } />
</>;
}
现在观察者逻辑是渲染流的一部分,发生在对话框之后,因此它应该正确更新。
当我遇到这个确切的问题时,这对我有用。
以下代码将在元素通过滚动进入或离开视口时立即触发状态更改
const dialog = useRef(),
[visible, set] = useState(false)
useEffect(() => {
const observer = new IntersectionObserver((e) => {
set(e[0].isIntersecting ? true : false)
}, {root: null, rootMargin: '0px', threshold: 0})
observer.observe(dialog.current)
return () => observer.disconnect()
}, [dialog.current])
return <div ref={dialog}>my dialog</div>
但如果我尝试这样的事情
const observer = new IntersectionObserver((e) => {
set(e[0].boundingClientRect.y <= 0 ? true : false)
}, {root: null, rootMargin: '0px', threshold: 0})
仅当触发重新渲染时状态才会更新,而我希望它在我滚动视口时根据观察到的元素的 boundingClientRect.y
值触发。
我发现完成这项工作的唯一方法是在 useEffect
中使用 window.onscroll
事件并将观察者放在其中,但它对我来说不太好。有没有比使用 window.onscroll
不同(更好)的方法?
这是因为在 useEffect
挂钩中实例化 IntersectionObserver
时 DOM 内容未完全加载。
不使用 window.onscroll
的解决方法是 运行 组件中的钩子并将你的 setter 作为道具传递。
像这样
function MyObserver({ selector, callback }){
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => callback(entries),
{ root: null, rootMargin: '0px', threshold: 0 });
const element = document.querySelector(selector);
observer.observe(element);
return () => {
observer.disconnect();
};
}, []);
return null;
}
function Main() {
[visible, set] = useState(false);
return <>
<div className="myDialog">my dialog</div>
<MyObserver selector=".myDialog"
callback={ (e) => { set(e[0].isIntersecting ? true : false); } } />
</>;
}
现在观察者逻辑是渲染流的一部分,发生在对话框之后,因此它应该正确更新。
当我遇到这个确切的问题时,这对我有用。