如何在remix-validated-form中重置动态数组输入的旧值?
解决remix-validated-form数组输入框重置旧值的问题
问题根源
你当前的代码存在两个核心问题:
- 输入框的
name属性未使用数组索引格式(如internalNumber[0]),表单无法区分不同数组项,导致旧值被错误保留。 - 未将输入框与表单状态绑定,也没有在下拉框数值变化时主动重置对应字段的状态。
解决方案
借助remix-validated-form的表单状态控制API,监听下拉框的数值变化,主动重置数组字段状态,同时修正输入框的命名与绑定逻辑:
步骤1:修正输入框命名与状态绑定
使用Controller组件或useField钩子,将每个输入框与表单的internalNumber[index]字段绑定,确保状态同步。
步骤2:监听下拉框变化,重置数组字段
当下拉框选中的数量(假设为selectedCount)改变时,调用表单的setValues方法,将internalNumber重置为对应长度的空数组,清空所有旧值。
完整代码示例
import { useForm, Controller } from "remix-validated-form"; import { useState, useEffect } from "react"; import { Form } from "@remix-run/react"; export default function ArrayInputForm() { // 下拉框选中的输入框数量 const [selectedCount, setSelectedCount] = useState(0); const { control, setValues, getValues } = useForm(); // 监听数量变化,重置数组字段 useEffect(() => { setValues({ ...getValues(), // 保留其他表单字段的值 internalNumber: Array(selectedCount).fill("") }); }, [selectedCount, setValues, getValues]); // 生成对应数量的输入框模板 const inputList = Array(selectedCount).fill(null); return ( <Form method="post"> {/* 下拉框组件 */} <select value={selectedCount} onChange={(e) => setSelectedCount(Number(e.target.value))} > <option value="0">0个输入框</option> <option value="1">1个输入框</option> <option value="2">2个输入框</option> <option value="3">3个输入框</option> </select> {/* 渲染数组输入框 */} {inputList.map((_, index) => ( <Controller key={index} name={`internalNumber[${index}]`} control={control} render={({ field }) => ( <input type="text" placeholder="Enter a number" {...field} className="mt-2 block w-full" /> )} /> ))} <button type="submit" className="mt-4 px-4 py-2 bg-blue-500 text-white"> 提交表单 </button> </Form> ); }
替代方案:使用useField钩子
如果不想使用Controller,可以直接用useField钩子绑定输入框:
import { useForm, useField } from "remix-validated-form"; import { useState, useEffect } from "react"; import { Form } from "@remix-run/react"; export default function ArrayInputForm() { const [selectedCount, setSelectedCount] = useState(0); const { setValues, getValues } = useForm(); useEffect(() => { setValues({ ...getValues(), internalNumber: Array(selectedCount).fill("") }); }, [selectedCount, setValues, getValues]); const inputList = Array(selectedCount).fill(null); return ( <Form method="post"> <select value={selectedCount} onChange={(e) => setSelectedCount(Number(e.target.value))} > <option value="0">0个输入框</option> <option value="1">1个输入框</option> <option value="2">2个输入框</option> </select> {inputList.map((_, index) => { const { field } = useField(`internalNumber[${index}]`); return ( <input key={index} type="text" placeholder="Enter a number" {...field} className="mt-2 block w-full" /> ); })} <button type="submit" className="mt-4 px-4 py-2 bg-blue-500 text-white"> 提交表单 </button> </Form> ); }
关键说明
- 必须使用
internalNumber[${index}]格式的name属性,remix-validated-form才能正确识别数组类型字段。 - 通过
setValues在下拉框变化时重置数组,确保新渲染的输入框初始值为空。 - 绑定
field对象到输入框,保证输入框值与表单状态实时同步,重置操作能立即生效。
内容的提问来源于stack exchange,提问作者jmanuelrosa
相关产品推荐
相关产品推荐

