You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Firebase待办应用中task.name无法显示的问题排查

React Firestore待办应用任务名称无法显示的修复方案

问题根源与修复点

  1. 数据访问路径错误
    在useEffect的快照处理逻辑中,你将每个Firestore文档转换为包含id和data的对象:

    {
      id: doc.id,
      data: doc.data()
    }
    

    但渲染列表时错误使用了{task.name},正确访问方式应为{task.data.name},这是名称不显示的直接原因。

  2. Firestore排序参数错误
    query(collection(db, 'tasks'), orderBy('created', 'name'))不符合API规范,orderBy的第二个参数应为排序方向(asc/desc)。若需按多字段排序,需拆分调用:

    const q = query(collection(db, 'tasks'), orderBy('created', 'desc'), orderBy('name'))
    
  3. 冗余的默认行为阻止
    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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 03:45:46