let { photos, isQuering, empty, error } = useFetch(brand, isOld);
useEffect(() => {
if (isOld) {
const { photos: photosTest } = useFetch(brand, isOld);
photos = photosTest;
}
}, [isOld]);
useFetch是我拥有的一个自定义钩子,当isOld状态为true时,我想带旧照片,通常会调用useEffect上面的代码并加载照片,但是我遇到错误,即未在体内调用useFetch一个功能组件,出现以下错误“无效的挂钩调用。只能在功能组件的主体内部调用挂钩。这可能由于以下原因之一发生:”,即我做错了很严重的事情看不到!如果您能帮助我,我将非常感谢!
由于Danko而进行编辑!钩!
import { useEffect, useState, useContext } from 'react';
import { useScrollPagination } from './flow-manager';
import { db } from '../../Firebase';
import { userContext } from '../appContext';
export default function fetch(brand, isOld) {
const {
userData: { uid },
} = useContext(userContext);
const [photos, setPhotos] = useState([]);
const [lastDoc, setLastDoc] = useState(undefined);
const [isQuering, setIsQuering] = useState(false);
const [empty, setEmpty] = useState(false);
const [error, setError] = useState();
const [finished, setFinished] = useState(false);
const shouldFetchMore = useScrollPagination();
const [shouldKeepFecthing, setShouldKeepFetching] = useState(false);
useEffect(() => {
if (isQuering || finished) return;
if (!lastDoc || shouldFetchMore || shouldKeepFecthing) {
setIsQuering(true);
let query = !isOld
? db
.collection('catalog-images')
.where('brandName', '==', brand)
.orderBy('timestamp', 'desc')
.endBefore(new Date().setDate(new Date().getDate() - 40))
.limit(20)
: db
.collection('catalog-images')
.where('brandName', '==', brand)
.where('photoPeriod', '==', 'Antiga')
.limit(20);
if (lastDoc) query = query.startAfter(lastDoc);
query
.get()
.then(snap => {
const newPhotos = [];
let valid = 0;
snap.forEach(doc => {
const { url, pricetag, timestamp } = doc.data();
if (!uid && pricetag === 'Sim') return;
brand && newPhotos.push({ url, timestamp });
valid += 1;
});
setPhotos(oldPhotos => [...oldPhotos, ...newPhotos]);
setShouldKeepFetching(valid < 10);
setEmpty(snap.empty);
setLastDoc(snap.docs[snap.docs.length - 1]);
setFinished(snap.docs.length < 20);
setIsQuering(false);
})
.catch(setError);
}
}, [!!lastDoc, shouldFetchMore, shouldKeepFecthing, isQuering]);
return { photos, isQuering, empty, error, fetch };
}
最后更新:
在这里,我称之为钩子:
let {
photos,
isQuering,
empty,
error,
useFetch: refetch,
} = useFetch(brand, isOld);
useEffect(() => {
if (isOld) {
let { photos: photosTest } = refetch(brand, isOld);
photos = photosTest;
setIsOld(false);
}
}, [isOld]);
Aaaand,这个钩子:
import { useEffect, useState, useContext } from 'react';
import { useScrollPagination } from './flow-manager';
import { db } from '../../Firebase';
import { userContext } from '../appContext';
export default function useFetch(brand, isOld) {
const {
userData: { uid },
} = useContext(userContext);
const [photos, setPhotos] = useState([]);
const [lastDoc, setLastDoc] = useState(undefined);
const [isQuering, setIsQuering] = useState(false);
const [empty, setEmpty] = useState(false);
const [error, setError] = useState();
const [finished, setFinished] = useState(false);
const shouldFetchMore = useScrollPagination();
const [shouldKeepFecthing, setShouldKeepFetching] = useState(false);
useEffect(() => {
if (isQuering || finished) return;
if (!lastDoc || shouldFetchMore || shouldKeepFecthing) {
setIsQuering(true);
let query = !isOld
? db
.collection('catalog-images')
.where('brandName', '==', brand)
.orderBy('timestamp', 'desc')
.endBefore(new Date().setDate(new Date().getDate() - 40))
.limit(20)
: db
.collection('catalog-images')
.where('brandName', '==', brand)
.where('photoPeriod', '==', 'Antiga')
.limit(20);
if (lastDoc) query = query.startAfter(lastDoc);
query
.get()
.then(snap => {
const newPhotos = [];
let valid = 0;
snap.forEach(doc => {
const { url, pricetag, timestamp } = doc.data();
if (!uid && pricetag === 'Sim') return;
brand && newPhotos.push({ url, timestamp });
valid += 1;
});
setPhotos(oldPhotos => [...oldPhotos, ...newPhotos]);
setShouldKeepFetching(valid < 10);
setEmpty(snap.empty);
setLastDoc(snap.docs[snap.docs.length - 1]);
setFinished(snap.docs.length < 20);
setIsQuering(false);
})
.catch(setError);
}
}, [!!lastDoc, shouldFetchMore, shouldKeepFecthing, isQuering]);
return { photos, isQuering, empty, error, useFetch };
}
最佳答案
我建议别的东西:
更新您的useFetch
,使其具有refetch
函数,将其添加到返回的对象中。
现在,可以像下面这样对已更新的钩子进行破坏:const { photos, isQuering, empty, error, refetch } = useFetch(brand);
您的useEfect可以这样使用:
useEffect(() => {
if(isOld) {
refetch();
setIsOld(false)
}
}, [isOld]);
更新:
您必须重命名custon挂钩以
use
开头。否则,无法做出反应将其与其他功能区分开。因此,与其将其命名为fetch
而不是将其重命名为useFetch
。