Я пытаюсь создать универсальный бесконечный скроллер с помощью React Hooks (и ResearchGate React Intersection Observer). Идея состоит в том, что родительский объект передаст сопоставленный массив данных JSX и обратный вызов, который асинхронно получит больше данных для этого массива, и когда наблюдатель пересечения сработает, потому что вы прокрутили достаточно вниз, чтобы показать значок загрузки, обратный вызов получитвызываемый и загружается больше данных.
Это работает достаточно хорошо, за исключением одного: esLint говорит мне, что, поскольку я вызываю функцию getMore (из реквизита) внутри useEffect, она должна зависеть от этого. эффект. Но поскольку в обратном вызове родителя я обращаюсь к длине его массива данных, этот массив должен быть зависимостью от useCallback. И затем этот обратный вызов изменяет массив.
TL; DR: я получаю условия гонки, которые вызывают асинхронный обратный вызов, если он не должен запускаться несколько раз, потому что ссылка на функцию обратного вызова изменяется и затем передаетсявплоть до того, что его вызывает.
Вот некоторый код для пояснения.
Обратный вызов в родительском:
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 и hasMore - это просто переменные состояния, ссообщения передаются как массив данных в подпорки для ребенка. Эта функция передается дочернему элементу в props, который имеет это (getMore - это деструктурированная опора для обратного вызова, isLoading - просто логическая переменная состояния):
useEffect(() => {
if (isLoading) {
(async () => {
await getMore();
setIsLoading(false);
})();
}
}, [isLoading, getMore]);
Я устанавливаю isLoading в true длявызвать эффект;но это также срабатывает, потому что ссылка getMore изменяется, когда родитель загружает данные, а функция запоминает. Этого не должно быть. Я мог бы просто отключить esLint для этой строки, но я предполагаю, что есть лучшее решение, и я хотел бы знать, что это такое.