javascript — React Hooks useEffect для вызова обратного обратного вызова из useCallback

React Hooks useEffect для вызова обратного вызова проп из useCallback

Я пытаюсь создать универсальный бесконечный скроллер с помощью React Hooks (и ResearchGate React Intersection Observer). Идея состоит в том, что родительский объект передаст сопоставленный массив данных JSX и обратный вызов, который асинхронно получит больше данных для этого массива, и когда наблюдатель пересечения сработает, потому что вы прокрутили достаточно вниз, чтобы показать значок загрузки, обратный вызов получит вызывается и больше данных загружается.

Он работает достаточно хорошо, за исключением одного: esLint говорит мне, что, поскольку я вызываю функцию getMore (из реквизита) внутри useEffect, она должна зависеть от этого эффекта. Но поскольку в обратном вызове родителя я обращаюсь к длине его массива данных, этот массив должен быть зависимостью от useCallback. И тогда этот обратный вызов изменяет массив.

TL; DR: Я получаю условия гонки, которые заставляют асинхронный обратный вызов запускаться несколько раз, когда это не должно происходить, потому что ссылка на функцию обратного вызова изменяется, а затем передается объекту, который ее вызывает.

Вот некоторый код, чтобы уточнить.

Обратный вызов в родительском:

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

posts и hasMore — это просто переменные состояния, при этом сообщения передаются в виде массива данных в подпорки дочернему элементу. Эта функция передается дочернему элементу в props, который имеет это (getMore — это деструктурированная опора для обратного вызова, isLoading — просто логическая переменная состояния):

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

Я устанавливаю isLoading в true, чтобы вызвать эффект; но это также срабатывает, потому что ссылка getMore изменяется, когда родитель загружает данные, а функция запоминает. Этого не должно быть. Я мог бы просто отключить esLint для этой строки, но я предполагаю, что есть лучшее решение, и я хотел бы знать, что это такое.

Понравилась статья? Поделиться с друзьями:
JavaScript & TypeScript
Adblock
detector