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

Next.js中设置默认属性数据及解决更新表单字段丢失问题

问题:Next.js更新表单未修改字段提交后被清空

我正在开发一个具备CRUD功能的React/Next.js应用,更新表单在提交时出现异常:

  • 不修改任何字段提交,title和content字段的数据会无故消失
  • 仅修改title字段提交,content字段会被清空

示例
修改前:

  • title: aaa
  • content: bbb

仅将title修改为aaaa后提交,结果:

  • title: aaaa
  • content: (空值)

原代码如下:

import Link from "next/link";
import { client } from "@/libs/client";
import { useRouter } from "next/router";
import React, { useState } from "react";

export default function Update ({ blog }) {
  const router = useRouter()
  const id = blog.id;
  const [title, setTitle] = useState("");
  const [content, setContent] = useState("");

  async function update(event) {
    event.preventDefault()

    client.update({
      endpoint: "blogs",
      content: {
        title: title,
        content: content,
      },
      contentId: id
    }).then((res) => {
      if (res.status === 401) {
        alert("Something wrong is happening")
      } else {
        alert("Editing is done")
        router.push(`/`)
      }
    })
  }

  return (
    <>
      <div className='main'>
        <h1 className=''>Edit page</h1>

        <div className="contents">

            <div>
                <form onSubmit={ update }>
                  <div>
                      <h2>Here's title</h2>
                      <input name="title" type="text" defaultValue={blog.title} onChange={(event) => setTitle(event.target.value)} />
                  </div>
                  <div>
                  <h2>Contents</h2>
                      <textarea name="content" defaultValue={blog.content} onChange={(event) => setContent(event.target.value)} ></textarea>
                  </div>
                <button type="submit">
                    <p>Submit</p>
                </button>
                </form>
            </div>
        </div>
      </div>
    </>
  );
}

export const getStaticPaths = async () => {
  const data = await client.get({ endpoint: "blogs" });

  const paths = data.contents.map((content) => `/blog/${content.id}/update`);
  return { paths, fallback: false };
};

export const getStaticProps = async (context) => {
  const id = context.params.id;
  const data = await client.get({ endpoint: "blogs", contentId: id });

  return {
    props: {
      blog: data,
    },
  };
};

问题原因

  1. 状态初始化错误:useState的初始值设为空字符串,而非传入的blog数据,导致未修改字段在提交时使用空值
  2. 表单绑定方式错误:使用defaultValue仅在初始渲染时赋值,未和状态双向绑定,表单显示的原始数据未同步到状态中

修复方案

1. 用blog数据初始化状态

将useState的初始值替换为blog中的对应字段:

const [title, setTitle] = useState(blog.title);
const [content, setContent] = useState(blog.content);

2. 用value绑定表单控件

把defaultValue改为value,确保表单控件的值始终和状态同步:

<input name="title" type="text" value={title} onChange={(event) => setTitle(event.target.value)} />
<textarea name="content" value={content} onChange={(event) => setContent(event.target.value)}></textarea>

修复后的完整代码

import Link from "next/link";
import { client } from "@/libs/client";
import { useRouter } from "next/router";
import React, { useState } from "react";

export default function Update ({ blog }) {
  const router = useRouter()
  const id = blog.id;
  // 用blog数据初始化状态
  const [title, setTitle] = useState(blog.title);
  const [content, setContent] = useState(blog.content);

  async function update(event) {
    event.preventDefault()

    client.update({
      endpoint: "blogs",
      content: {
        title: title,
        content: content,
      },
      contentId: id
    }).then((res) => {
      if (res.status === 401) {
        alert("Something wrong is happening")
      } else {
        alert("Editing is done")
        router.push(`/`)
      }
    })
  }

  return (
    <>
      <div className='main'>
        <h1 className=''>Edit page</h1>

        <div className="contents">

            <div>
                <form onSubmit={ update }>
                  <div>
                      <h2>Here's title</h2>
                      {/* 用value绑定状态 */}
                      <input name="title" type="text" value={title} onChange={(event) => setTitle(event.target.value)} />
                  </div>
                  <div>
                  <h2>Contents</h2>
                      {/* 用value绑定状态 */}
                      <textarea name="content" value={content} onChange={(event) => setContent(event.target.value)} ></textarea>
                  </div>
                <button type="submit">
                    <p>Submit</p>
                </button>
                </form>
            </div>
        </div>
      </div>
    </>
  );
}

export const getStaticPaths = async () => {
  const data = await client.get({ endpoint: "blogs" });

  const paths = data.contents.map((content) => `/blog/${content.id}/update`);
  return { paths, fallback: false };
};

export const getStaticProps = async (context) => {
  const id = context.params.id;
  const data = await client.get({ endpoint: "blogs", contentId: id });

  return {
    props: {
      blog: data,
    },
  };
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 06:45:59