Next.js尝试将输入值写入JSON失败,求排查前端问题
前端问题分析与修复方案
核心问题梳理
- 状态类型不匹配:初始
useState取的是单个字符串类型的title,但onChange里把状态设置成了{text: e.target.value}对象,导致后续赋值逻辑出错。 - 表单默认提交未拦截:注释了
e.preventDefault(),点击提交会触发页面刷新,前端状态直接丢失,无法验证修改效果。 - 直接修改只读模块:导入的
PcosData是静态只读模块,直接修改它既无法持久化到本地JSON文件,也不符合React状态管理规范。 - 状态与列表元素未绑定:循环生成的所有表单共用同一个
title状态,导致输入框内容互相干扰。 - 静态JSON的局限性:在Next.js中直接导入JSON文件是静态加载的,无法获取实时更新的数据,应通过服务端逻辑动态读取。
修复后的完整代码
import { useState } from "react"; import fs from "fs/promises"; import path from "path"; export async function getServerSideProps({ req, res }) { // 动态读取JSON文件,确保获取最新数据 const filePath = path.join(process.cwd(), "data/pcos.json"); const fileContent = await fs.readFile(filePath, "utf8"); const pcosData = JSON.parse(fileContent); // 处理POST请求,完成JSON文件的更新 if (req.method === "POST") { const { id, title } = req.body; const updatedData = { ...pcosData, "pcos-first": pcosData["pcos-first"].map(item => item.id === id ? { ...item, title } : item ) }; await fs.writeFile(filePath, JSON.stringify(updatedData, null, 2)); return { props: { pcosData: updatedData } }; } return { props: { pcosData } }; } export default function AdminPcos({ pcosData }) { // 用数组状态维护所有元素,初始化时从服务端props获取数据 const [items, setItems] = useState(pcosData["pcos-first"]); const handleChange = (id, newTitle) => { // 更新对应元素的title,保持其他元素不变 setItems(prevItems => prevItems.map(item => item.id === id ? { ...item, title: newTitle } : item ) ); }; const handleSubmit = async (e, id) => { e.preventDefault(); const currentItem = items.find(item => item.id === id); if (!currentItem) return; // 发送POST请求到服务端,触发文件更新 try { await fetch("/adminPcos", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ id, title: currentItem.title }) }); alert("更新成功"); } catch (error) { console.error("更新失败:", error); alert("更新失败"); } }; return ( <div> <h1>PCOS内容管理</h1> {items.map((item) => ( <form key={item.id} onSubmit={(e) => handleSubmit(e, item.id)}> <input type="text" className="name" name="title" value={item.title} onChange={(e) => handleChange(item.id, e.target.value)} /> <button type="submit">提交修改</button> </form> ))} </div> ); }
关键修复说明
- 服务端动态读写JSON:在
getServerSideProps中完成JSON文件的读取与写入,保证数据实时性和持久化。 - 独立元素状态管理:用数组状态维护所有列表元素,每个输入框的修改仅对应自身元素,避免状态冲突。
- 拦截表单默认行为:保留
e.preventDefault(),防止页面刷新,确保前端状态正常更新。 - 前后端数据同步:前端修改状态后,通过POST请求将数据传给服务端,由服务端完成文件写入,符合前后端分离逻辑。
内容的提问来源于stack exchange,提问作者thecorses
相关产品推荐
相关产品推荐

