简体   繁体   English

React Hooks useEffect 从 useCallback 调用道具回调

[英]React Hooks useEffect to call a prop callback from useCallback

I'm trying to make a general-purpose infinite scroller with React Hooks (and the ResearchGate React Intersection Observer).我正在尝试使用 React Hooks(和 ResearchGate React Intersection Observer)制作一个通用的无限滚动器。 The idea is that a parent will pass down a mapped JSX array of data and a callback that will asynchronously get more data for that array, and when the intersection observer fires because you've scrolled down enough to reveal the loading icon, the callback gets called and more data is loaded.这个想法是,父级将传递一个映射的 JSX 数据数组和一个回调,该回调将异步获取该数组的更多数据,并且当交叉点观察者因为您向下滚动到足以显示加载图标而触发时,回调会获取调用并加载更多数据。

It works well enough, except one thing: esLint tells me that because I'm calling the getMore function (from the props) inside a useEffect, it must be a dependency of that effect.它工作得很好,除了一件事:esLint 告诉我,因为我在 useEffect 中调用 getMore function(来自道具),所以它必须是该效果的依赖项。 But because in the parent's callback I'm accessing its data array's length, that array must be a dependency of useCallback there.但是因为在父回调中我正在访问其数据数组的长度,所以该数组必须是 useCallback 的依赖项。 And then that callback modifies the array.然后该回调会修改数组。

TL;DR: I'm getting race conditions that cause the async callback to trigger multiple times when it shouldn't, because the callback function reference is changing and then being passed down to the thing that's calling it. TL; DR:我遇到了导致异步回调在不应该触发的情况下多次触发的竞争条件,因为回调 function 引用正在更改,然后被传递给调用它的东西。

Here's some code to clarify.这里有一些代码来澄清。

The callback in the parent:父级中的回调:

const loadData = useCallback(async () => {
    if (hasMore) {
        const startAmount = posts.length;
        for (let i = 0; i < 20; ++i) {
            posts.push(`I am post number ${i + startAmount}.`);
            await delay(100);
        }
        setPosts([...posts]);
        setHasMore(posts.length < 100);
    }
}, [posts, hasMore]);

posts and hasMore are just state variables, with posts being passed down as the data array in props to the child. posts 和 hasMore 只是 state 变量,posts 作为 props 中的数据数组传递给孩子。 That function is being passed to the child in props, which has this (getMore is the destructured prop for the callback, isLoading is just a boolean state variable):那个 function 被传递给道具中的孩子,它有这个(getMore 是回调的解构道具,isLoading 只是一个 boolean state 变量)

useEffect(() => {
    if (isLoading) {
        (async () => {
            await getMore();
            setIsLoading(false);
        })();
    }
}, [isLoading, getMore]);

I'm setting isLoading to true to trigger the effect;我将 isLoading 设置为 true 以触发效果; but it's also triggering because getMore's reference changes when the parent loads data and the function memoizes.但它也会触发,因为当父级加载数据并且 function 记忆时,getMore 的引用发生了变化。 That shouldn't happen.那不应该发生。 I could just disable esLint for that line, but I assume there's a better solution, and I'd like to know what it is.我可以为该行禁用 esLint,但我认为有更好的解决方案,我想知道它是什么。

Solution: don't use useEffect at all.解决方案:根本不要使用 useEffect 。 Just call the loading function directly from the observer and have that set isLoading and call the callback rather than having isLoading trigger the callback.只需直接从观察者调用加载 function 并设置 isLoading 并调用回调,而不是让 isLoading 触发回调。

const loadData = async (observerEntry) => {
    if (observerEntry.isIntersecting && !disabled && !isLoading) {
        setIsLoading(true);
        await getMore();
        setIsLoading(false);
    }
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 与useEffect一起使用时如何防止触发useCallback(并遵守eslint-plugin-react-hooks)? - How to prevent useCallback from triggering when using with useEffect (and comply with eslint-plugin-react-hooks)? React Hooks useCallback 和 useEffect 导致反应应用程序中的无限循环 - React Hooks useCallback and useEffect causes infinite loop in react application 你可以从 React.js 中的 useEffect 传递钩子作为 prop 值吗? - Can you pass hooks as a prop value from an useEffect in React.js? React Hooks useEffect Change Fetch URL 调用 - React Hooks useEffect Change Fetch URL Call 如何使用渲染之间的钩子调用渲染道具从其父组件提供的回调 - How to call callback provided by render prop from its parent component using hooks between renders 用 useEffect 钩子替换 react 钩子中的 setState 回调,用于复杂的场景不起作用 - Replace of setState callback in react hook with useEffect hooks for complicated scenario not working 从 useEffect 返回的反应钩子之间的区别 - Difference between react hooks returning from useEffect 反应钩子:从 useEffect 分派动作 - React hooks: dispatch action from useEffect 在反应测试渲染器中调用道具回调不会更新钩子 - Calling prop callback in react test renderer doesn't update hooks 如何根据从第一次获得的值进行第二次 API 调用。 使用 React 和 useEffect 钩子 - How to Make A second API call based on the value gotten from the first. with React and useEffect hooks
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM