React中无需使用await执行Firestore查询的方法及相关问题解决
问题原因与解决方法
1. await报错的原因与非await实现方案
await 关键字只能在被 async 标记的异步函数内部使用,直接在普通函数、全局作用域下使用会触发编译报错。不需要await的替代方案直接使用Promise的.then/.catch链式调用即可,对应你场景的代码如下:
const librosRef = db.collection('libros'); const queryRef = librosRef.where('grado', '==', '4° Grado'); queryRef.get() .then(snapshot => { if (snapshot.empty) { console.log('No matching documents.'); return; } snapshot.forEach(doc => { console.log(doc.id, '=>', doc.data()); }); }) .catch(err => { console.log('查询出错:', err); });
2. useEffect链式调用写法的问题修复
你写的.then写法逻辑方向是对的,不生效主要是以下几个问题:
- 同时使用
orderBy和where的复合查询,Firebase要求必须提前创建对应索引,未创建索引会导致查询直接失败,且你没有加.catch捕获错误,无法感知到报错 - React列表循环必须指定唯一
key属性,你没有加key可能导致渲染异常 libros状态需要初始化为空数组,避免初始渲染时调用map报错
修正后的完整代码如下:
// 先初始化libros为空数组 const [libros, setLibros] = useState([]); useEffect(() => { // 可先去掉orderBy测试基础查询是否正常,避免索引问题阻塞验证 db.collection("libros") .where('grado', '==', '4° Grado') .get() .then((snapshot) => { const tempData = []; snapshot.forEach((doc) => { tempData.push({ id: doc.id, // 保存文档id作为循环key ...doc.data() }); }); setLibros(tempData); }) .catch(err => { // 这里会打印具体错误,若为索引问题,错误信息会直接给出索引创建入口,点击创建等待生效即可 console.error("查询出错:", err); }); }, []); // 渲染部分修正 <tbody> {libros.map((e) => ( <tr key={e.id}> <td> <input onChange={(event) => { let checked = event.target.checked; // 这里补充你自己的勾选逻辑即可 }} type="checkbox" /> </td> <td>{e.grado}</td> <td>{e.descripcion}</td> <td>{e.editorial}</td> <td>${parseFloat(e.precio).toFixed(2)}</td> </tr> ))} </tbody>
如果需要保留按precio排序的逻辑,按照错误提示创建对应索引后,把.orderBy("precio")加回查询链即可。
内容的提问来源于stack exchange,提问作者React Enjoyer
相关产品推荐
相关产品推荐

