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

如何在Next.js中使用Server Actions设置表单默认值

解决React受控输入警告及表单值无法更新的问题

问题分析

  1. 受控输入警告:尽管你给state设置了初始空字符串,但如果formValues props在组件挂载后才传入(比如编辑场景下异步获取数据),或者初始化时未合并formValues,会导致输入框短暂从“未受控”切换为“受控”,触发警告。
  2. useEffect无法更新表单值:原useEffect依赖为空数组,仅在组件挂载时执行一次;若formValues是动态变化的(比如编辑数据加载完成),不会触发state更新。同时直接使用dataForm存在闭包问题,可能导致更新不及时。

解决方案

1. 初始化state时合并传入的formValues

将formValues作为初始state的一部分,确保输入框从始至终处于受控状态,避免undefined到有值的切换。

2. 用函数式更新处理表单输入

在changeHandler中使用setFormValues的函数式形式,确保每次更新都基于最新的state,规避闭包陷阱。

3. 监听formValues变化同步更新state

修改useEffect的依赖数组,加入formValues,当props的表单值变化时,自动同步到组件内部state。

修改后的完整代码

"use client";

import SubmitBtn from "@/app/components/SubmitBtn";
import React, { useEffect, useState } from "react";

const SuccessIndicatorForm = ({ state, formAction, formValues }: any) => {
  // 初始化state:优先使用传入的formValues,无则用默认空值
  const [dataForm, setFormValues] = useState(() => ({
    major_final_output: "",
    title: "",
    target_measure: "",
    ...formValues // 合并传入的表单值
  }));

  // 监听formValues变化,同步更新state
  useEffect(() => {
    if (formValues) {
      setFormValues(prev => ({
        ...prev,
        ...formValues
      }));
    }
  }, [formValues]); // 依赖加入formValues

  // 函数式更新,确保基于最新state修改
  const changeHandler = (e: any) => {
    setFormValues(prev => ({
      ...prev,
      [e.target.name]: e.target.value
    }));
  };

  return (
    <div className="max-w-max px-4 py-8 bg-white rounded-lg shadow dark:bg-gray-800 sm:px-6 md:px-8 lg:px-10 m-auto mt-20 text-white">
      <form action={formAction} className="flex flex-col w-full justify-around">
        <div className="relative">
          <div className="flex flex-col justify-between">
            <div>
              <label htmlFor="major_final_output">Major Final Output:</label>
              <input
                value={dataForm.major_final_output}
                onChange={changeHandler}
                type="text"
                id="major_final_output"
                name="major_final_output"
                placeholder="MFO 1: Human Resource Management and Development Services"
                className="rounded-lg py-1 px-1 m-2 text-black"
                required
              />
            </div>
            {/* 补充剩余表单字段 */}
            <div>
              <label htmlFor="title">Title:</label>
              <input
                value={dataForm.title}
                onChange={changeHandler}
                type="text"
                id="title"
                name="title"
                className="rounded-lg py-1 px-1 m-2 text-black"
                required
              />
            </div>
            <div>
              <label htmlFor="target_measure">Target Measure:</label>
              <input
                value={dataForm.target_measure}
                onChange={changeHandler}
                type="text"
                id="target_measure"
                name="target_measure"
                className="rounded-lg py-1 px-1 m-2 text-black"
                required
              />
            </div>
            <SubmitBtn />
          </div>
        </div>
        <p role="status">{state?.message}</p>
      </form>
    </div>
  );
};

export default SuccessIndicatorForm;

场景适配说明

  • 新建数据:不传入formValues,组件使用默认空值初始化,正常提交新数据。
  • 编辑数据:传入从接口获取的已有formValues,组件自动填充表单,支持编辑后提交。
  • 函数式更新能保证输入响应的实时性,避免因闭包导致的状态不同步问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 09:05:39