React Firebase待办应用中task.name无法显示的问题排查
React Firestore待办应用任务名称无法显示的修复方案
问题根源与修复点
数据访问路径错误
在useEffect的快照处理逻辑中,你将每个Firestore文档转换为包含id和data的对象:{ id: doc.id, data: doc.data() }但渲染列表时错误使用了
{task.name},正确访问方式应为{task.data.name},这是名称不显示的直接原因。Firestore排序参数错误
query(collection(db, 'tasks'), orderBy('created', 'name'))不符合API规范,orderBy的第二个参数应为排序方向(asc/desc)。若需按多字段排序,需拆分调用:const q = query(collection(db, 'tasks'), orderBy('created', 'desc'), orderBy('name'))冗余的默认行为阻止
handleChange函数中的event.preventDefault()属于冗余代码,会干扰输入框正常输入,建议移除。
修正后的完整代码
import React, { useEffect, useState } from "react"; import { v4 as uuidv4 } from "uuid"; import { db } from "./utils/firebase"; import { collection, addDoc, Timestamp, query, orderBy, onSnapshot } from "firebase/firestore"; export default function Todo() { const [name, setName] = useState(""); const [isDoubleClicked, setDoubleClicked] = useState(false); const [tasks, setTasks] = useState([]); function handleChange(event) { setName(event.target.value); } const handleAdd = async (e) => { e.preventDefault(); try { await addDoc(collection(db, 'tasks'), { name: name, id: uuidv4(), completed: false, created: Timestamp.now(), }); setName(""); // 添加后清空输入框,提升体验 } catch (err) { alert(err); } }; useEffect(() => { // 修正排序参数,按创建时间倒序排列 const q = query(collection(db, 'tasks'), orderBy('created', 'desc')); onSnapshot(q, (querySnapshot) => { setTasks(querySnapshot.docs.map(doc => ({ id: doc.id, data: doc.data() }))); }); }, []); function handleClick(event) { if (event.detail === 2) { console.log("double click"); setDoubleClicked(current => !current); event.currentTarget.classList.toggle('double-clicked'); } } return ( <div> <div> <div> <h1>To Do List App</h1> <p>Double click to mark an item off, click on "X" to delete an item, and drag items to reorder.</p> </div> <input type="text" value={name} onChange={handleChange} placeholder="输入任务名称" /> <button type="submit" onClick={handleAdd} disabled={!name.trim()} // 空内容时禁用按钮 > Add </button> </div> <ol> {tasks.map((task) => ( <li id={task.id} key={task.id} completed={task.data.completed} onClick={handleClick} > {task.data.name} <button>x</button> </li> ))} </ol> </div> ); };
额外优化说明:
- 添加输入框清空逻辑,提升用户体验
- 新增按钮禁用逻辑,避免添加空任务
- 补充输入框占位提示
内容的提问来源于stack exchange,提问作者Julian
相关产品推荐
相关产品推荐

