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

Next.js Todo应用状态管理问题:编辑功能无法正常实现

Todo应用编辑切换功能故障修复指南(Next.js + Prisma + PostgreSQL)

我编程9个月,刚接触状态管理,问题可能比较基础,见谅。用Next.js、Prisma ORM、PostgreSQL做Todo应用,想要实现点编辑按钮弹出编辑表单,同时编辑按钮换成保存按钮的功能。试了用[newTitle, setNewTitle]存新标题、[isEditing, setIsEditing]管编辑状态,写了handleChange处理表单输入,但功能就是跑不起来,调了一周没解决,附上相关代码和错误截图,求帮忙。


相关代码

Todo项组件

// Next.js 13+ 必须添加客户端组件指令
'use client';

import { useState } from 'react';

export default function TodoItem({ todo, onUpdate }) {
  const [isEditing, setIsEditing] = useState(false);
  const [newTitle, setNewTitle] = useState(todo.title);

  const handleChange = (e) => {
    setNewTitle(e.target.value);
  };

  const toggleEdit = () => {
    setIsEditing(!isEditing);
    // 取消编辑时恢复原标题
    if (isEditing) setNewTitle(todo.title);
  };

  const saveTodo = async () => {
    if (!newTitle.trim()) return; // 空标题不提交
    await onUpdate(todo.id, newTitle);
    setIsEditing(false);
  };

  return (
    <div className="todo-item">
      {/* 切换显示标题或编辑输入框 */}
      {isEditing ? (
        <input
          type="text"
          value={newTitle}
          onChange={handleChange}
          autoFocus
          className="edit-input"
        />
      ) : (
        <span className={todo.done ? 'todo-title done' : 'todo-title'}>
          {todo.title}
        </span>
      )}

      {/* 切换显示编辑/保存按钮 */}
      {isEditing ? (
        <button onClick={saveTodo} className="save-btn">保存</button>
      ) : (
        <button onClick={toggleEdit} className="edit-btn">编辑</button>
      )}
      <button className="delete-btn">删除</button>
    </div>
  );
}

更新Todo的API路由

// app/api/todos/[id]/route.js
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export async function PUT(req, { params }) {
  const { id } = params;
  const { title } = await req.json();

  try {
    const updatedTodo = await prisma.todo.update({
      where: { id: parseInt(id) },
      data: { title: title.trim() },
    });
    return Response.json(updatedTodo);
  } catch (err) {
    console.error(err);
    return Response.json({ error: '更新失败,请重试' }, { status: 500 });
  }
}

Prisma Schema

model Todo {
  id    Int     @id @default(autoincrement())
  title String  @db.VarChar(255)
  done  Boolean @default(false)
}

必查故障点及修复方法

  1. 缺少客户端组件指令
    Next.js 13+ 默认是服务器组件,使用useState必须在组件顶部加'use client',否则直接报错,这是新手高频踩坑点。

  2. 状态作用域错误
    若把isEditing放在父列表组件中,会导致所有Todo项同时进入编辑模式。必须将isEditing和newTitle放在单个TodoItem组件内,让每个Todo项独立维护自身编辑状态。

  3. 表单绑定逻辑错误
    检查input的value是否绑定newTitle、onChange是否正确调用handleChange。可在handleChange中添加console.log(e.target.value),验证输入时状态是否更新。

  4. 保存逻辑缺失校验
    空标题禁止提交,添加if (!newTitle.trim()) return判断;需先调用API完成数据库更新,再切换isEditing状态,避免更新失败时丢失用户输入。

  5. API路由参数类型不匹配
    Prisma中id为整数,路由params.id是字符串,必须转换为parseInt(id),否则会报“找不到记录”错误。通过浏览器开发者工具查看Network请求,确认请求体是否携带title、响应状态码是否为200。

  6. 条件渲染逻辑写反
    检查是否把isEditing写成!isEditing,比如误将“编辑状态显示保存按钮”写成“非编辑状态显示保存按钮”,导致按钮无法正常切换。

内容的提问来源于stack exchange,提问作者Jimfinn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 09:44:52