首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >是否有可能避免useCallback自定义React上的“eslint(deps钩子/详尽-deps)”错误?

是否有可能避免useCallback自定义React上的“eslint(deps钩子/详尽-deps)”错误?
EN

Stack Overflow用户
提问于 2020-08-12 15:25:26
回答 2查看 429关注 0票数 0

使用以下自定义的React与IntersectionObserver进行交互

代码语言:javascript
运行
复制
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的正确方法是什么?

EN

回答 2

Stack Overflow用户

发布于 2020-08-12 15:31:36

修复方法是从options中重构所需的属性,并在依赖数组中设置它们。这样,您就不需要options,而钩子只有在这三个值发生变化时才会被调用。

代码语言:javascript
运行
复制
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 };
票数 1
EN

Stack Overflow用户

发布于 2020-08-12 16:13:29

您应该始终在dep数组中提供所有必需的值,以防止它使用以前缓存的函数和陈旧的值。修复您的情况的一个选项是备注options对象,因此只有一个新对象在值更改时传递,而不是在每次重呈现时传递:

代码语言:javascript
运行
复制
// 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); 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63379769

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档