使用以下自定义的React与IntersectionObserver进行交互
import { useCallback, useRef, useState } from 'react';
type IntersectionObserverResult = [(node: Element | null) => void, IntersectionObserverEntry?];
function useIntersectionObserver(options: IntersectionObserverInit): IntersectionObserverResult {
const intersectionObserver = useRef<IntersectionObserver>();
const [entry, setEntry] = useState<IntersectionObserverEntry>();
const ref = useCallback(
(node) => {
if (intersectionObserver.current) {
console.log('[useInterSectionObserver] disconnect()');
intersectionObserver.current.disconnect();
}
if (node) {
intersectionObserver.current = new IntersectionObserver((entries) => {
console.log('[useInterSectionObserver] callback()');
console.log(entries[0]);
setEntry(entries[0]);
}, options);
console.log('[useInterSectionObserver] observe()');
intersectionObserver.current.observe(node);
}
},
[options.root, options.rootMargin, options.threshold]
);
return [ref, entry];
}
export { useIntersectionObserver };ESLint抱怨:
React useCallback缺少一个依赖项:“options”。要么包含它,要么删除依赖数组。
如果我用[options]替换依赖项数组,ESLint就不再抱怨了,但是现在有一个更大的问题,就是呈现无限循环。
在不出现eslint(react-hooks/exhaustive-deps)错误的情况下,实现这个自定义React的正确方法是什么?
发布于 2020-08-12 15:31:36
修复方法是从options中重构所需的属性,并在依赖数组中设置它们。这样,您就不需要options,而钩子只有在这三个值发生变化时才会被调用。
import { useCallback, useRef, useState } from 'react';
type IntersectionObserverResult = [(node: Element | null) => void, IntersectionObserverEntry?];
function useIntersectionObserver(options: IntersectionObserverInit): IntersectionObserverResult {
const intersectionObserver = useRef<IntersectionObserver>();
const [entry, setEntry] = useState<IntersectionObserverEntry>();
const { root, rootMargin, threshold } = options;
const ref = useCallback(
(node) => {
if (intersectionObserver.current) {
console.log('[useInterSectionObserver] disconnect()');
intersectionObserver.current.disconnect();
}
if (node) {
intersectionObserver.current = new IntersectionObserver((entries) => {
console.log('[useInterSectionObserver] callback()');
console.log(entries[0]);
setEntry(entries[0]);
}, options);
console.log('[useInterSectionObserver] observe()');
intersectionObserver.current.observe(node);
}
},
[root, rootMargin, threshold]
);
return [ref, entry];
}
export { useIntersectionObserver };发布于 2020-08-12 16:13:29
您应该始终在dep数组中提供所有必需的值,以防止它使用以前缓存的函数和陈旧的值。修复您的情况的一个选项是备注options对象,因此只有一个新对象在值更改时传递,而不是在每次重呈现时传递:
// in parent
// this passes a new obj on every re-render
const [ref, entry] = useIntersectionObserver({ root, rootMargin, threshold });
// this will only pass a new obj if the deps change
const options = useMemo(() => ({ root, rootMargin, threshold }), [root, rootMargin, threshold]);
const [ref, entry] = useIntersectionObserver(options); https://stackoverflow.com/questions/63379769
复制相似问题