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

09-25 13:49