React从Firebase读取数据返回空数组,如何解决?
问题:Todo CRUD应用无法正确渲染数据
我正在开发一个简易的Todo CRUD应用,无法将数据渲染到页面上。目前console.log(doc.data())能正常显示所有数据集,但todos数组仅能获取首个值或返回空数组,求解决思路。
const Home = () => { const [todos,setTodos] = useState([]); const getTodos = async () =>{ const querySnapshot = await getDocs(collection(db, "todos")); querySnapshot.forEach((doc) => { setTodos([...todos,doc.data()]) console.log(doc.data()) console.log(todos) }); } useEffect(()=>{ getTodos(); },[]) return ( <div>Home</div> ) }
问题原因
循环调用setTodos([...todos, doc.data()])时,todos始终是初始的空数组——因为React状态更新是异步的,循环里的每一次setTodos都捕获了初始的todos值,最终只会保留最后一次添加的数据,或因异步时序问题仅显示第一条。
解决思路
一次性收集数据后更新状态
先把所有todo数据存入临时数组,再一次性调用setTodos,避免多次异步更新的冲突:const getTodos = async () =>{ const querySnapshot = await getDocs(collection(db, "todos")); const newTodos = querySnapshot.docs.map(doc => doc.data()); setTodos(newTodos); }用函数式更新确保状态最新
如果需要逐步更新状态,改用setTodos的函数式写法,每次更新都基于上一次的最新状态:querySnapshot.forEach((doc) => { setTodos(prevTodos => [...prevTodos, doc.data()]); });补充页面渲染逻辑
最后要在组件的返回值里渲染todos数据,比如:return ( <div> <h2>我的待办</h2> {todos.map((todo, idx) => ( <div key={idx} className="todo-item"> {todo.title} {/* 替换成你的todo实际字段名 */} </div> ))} </div> )
内容的提问来源于stack exchange,提问作者jungs
相关产品推荐
相关产品推荐

