Next.js Todo应用状态管理问题:编辑功能无法正常实现
我编程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) }
必查故障点及修复方法
缺少客户端组件指令
Next.js 13+ 默认是服务器组件,使用useState必须在组件顶部加'use client',否则直接报错,这是新手高频踩坑点。状态作用域错误
若把isEditing放在父列表组件中,会导致所有Todo项同时进入编辑模式。必须将isEditing和newTitle放在单个TodoItem组件内,让每个Todo项独立维护自身编辑状态。表单绑定逻辑错误
检查input的value是否绑定newTitle、onChange是否正确调用handleChange。可在handleChange中添加console.log(e.target.value),验证输入时状态是否更新。保存逻辑缺失校验
空标题禁止提交,添加if (!newTitle.trim()) return判断;需先调用API完成数据库更新,再切换isEditing状态,避免更新失败时丢失用户输入。API路由参数类型不匹配
Prisma中id为整数,路由params.id是字符串,必须转换为parseInt(id),否则会报“找不到记录”错误。通过浏览器开发者工具查看Network请求,确认请求体是否携带title、响应状态码是否为200。条件渲染逻辑写反
检查是否把isEditing写成!isEditing,比如误将“编辑状态显示保存按钮”写成“非编辑状态显示保存按钮”,导致按钮无法正常切换。
内容的提问来源于stack exchange,提问作者Jimfinn

