首页 > 解决方案 > 使用 React Hooks 时如何避免两次获取数据

问题描述

我正在尝试从 Firestore 数据库中获取一组问题,然后将它们存储在本地数组中以供以后在测验中使用。当我正在努力获取数据时,它是异步运行的。我之前处理过这个问题,解决方案是一个useEffect()钩子和有条件的渲染组件。

我的代码目前如下所示:

var questions = [];
var collection = useRef('Planning');
var [loading, setLoading] = useState(true);  

useEffect(() => {
        if (props.track === 'Testing & Deployment') {
            collection.current = 'Test_Deploy';
        } else {
            collection.current = props.track;
        }

        if(questions.length !== 0){
            setLoading(false)
        } else {
            var questionSet = db.collection('Quizzes').doc(collection.current).collection('Questions')

            questionSet.withConverter(questionConverter).get().then(function(response) {
                    response.forEach(document => {
                        var question = document.data();
                        // running asynch - need to address
                        console.log('Question in')
                        questions.push(question)
                    })
            })
            setLoading(false)
        }

    }, [props.track, questions])}

根据位置setLoading()的不同,组件要么根本不会重新渲染,要么会从 Firestore 中双重获取数据。我试过玩弄useCallback()无济于事,并且还发现这可能是 React 的问题StrictMode

关于如何修复我的代码以便在获取所有问题后重新呈现页面而不重复获取它们的任何建议?

标签: reactjsgoogle-cloud-firestorereact-hooks

解决方案


要在组件挂载时获取一次数据,您可以指定一个空的依赖项数组。我还建议将questions对象移动到本地组件状态。由于状态是在循环中更新的,因此您应该使用功能状态更新将每个新问题添加到数组中。

const [questions, setQuestions] = useState([]);
const [loading, setLoading] = useState(true);

useEffect(() => {
  const questionSet = db
    .collection("Quizzes")
    .doc(collection.current)
    .collection("Questions");

  questionSet
    .withConverter(questionConverter)
    .get()
    .then(function (response) {
      response.forEach((document) => {
        const question = document.data();
        setQuestions(questions => [...questions, question]);
      });
    });

  setLoading(false);
}, []);

如果 linter 抱怨缺少依赖项,那么您需要添加它们并对数据获取进行适当的条件检查,或者添加注释以忽略/禁用具有依赖项数组的行的 linter // eslint-disable-next-line react-hooks/exhaustive-deps,.


推荐阅读