reactjs - 使用 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
。
关于如何修复我的代码以便在获取所有问题后重新呈现页面而不重复获取它们的任何建议?
解决方案
要在组件挂载时获取一次数据,您可以指定一个空的依赖项数组。我还建议将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
,.
推荐阅读
- reactjs - Metro 遇到错误“无法读取未定义反应本机的属性“transformFile”
- java - 转换列表
到地图 > 由 Document 对象中的变量与 Java 8 流 (lamda) 在一行中分组 - javascript - 将两个 AJAX 源变量传递给 php 文件
- c++builder-10.4-sydney - C++ Builder 10.4.2:CLANG 核心/库有什么变化吗?
- python - pnadas read_gbq 不工作并显示错误
- assembly - 为什么当我将 qword 直接存储到堆栈时 NASM 会发出警告?
- php - 使用 curl 从 API 获取此信息
- c - 那个 C 程序中存储了什么 k?
- function - 例程、子例程和功能有何不同?
- c - C编程,无限循环中的线程最终停止