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

如何使用Preact Signal在表单提交后重置输入字段?

关于Signal表单提交后重置输入字段的问题

请问是否可以使用Signal在表单提交后清除/重置输入字段?以下为示例代码:

const formData = signal({ firstName: "", lastName: "" })

const Register = () => {

//function to make all keys pairs equal to an empty string
function initialState(input) {
        return Object.keys(input).forEach(i => input[i] = "");
};

function setFormData(name, value) {
        return formData.value = {...formData.value, [name]: value};
};

function handleInputChange (e) {
 const { name, value } = e.target;
 setFormData(name, value);
};
function registerUser (e){
 e.preventDefault();
 initialState(formData.value);
};

return(
  <form onSubmit={registerUser}>
   <input
    type="text"
    placeholder="First Name"
    name="firstName"
    value={formData.value.firstName}
    onChange="{handleInputChange}"
   />
   <input
    type="text"
    placeholder="Last Name"
    name="lastName"
    value={formData.value.lastName}
    onChange="{handleInputChange}"
   />
<button>Submit</button>
  </form>
)
}

我发现点击提交按钮后,输入字段不会立即清空,只有在输入内容时才会清空。与useState不同,useState提交后会直接清空所有字段,我怀疑这是因为Signal不会触发组件重新渲染导致的,恳请解答。


问题原因

你的猜测完全正确。Signal的响应式机制依赖对象引用变化:当你直接修改formData.value内部的属性时(比如input[i] = ""),formData.value本身的引用没改变,Signal无法检测到内部属性更新,自然不会触发组件重渲染,输入框的value也就不会同步变化。只有当你用formData.value = 新对象的方式替换整个值时,Signal才会感知到变化并触发重渲染。

另外代码里还有个小错误:onChange="{handleInputChange}"多了引号,JSX里事件绑定不能加引号,要写成onChange={handleInputChange},否则事件不会生效。

解决方案

核心思路是替换整个formData.value为新对象,而不是修改原对象的属性,这样才能触发Signal的响应式更新。

方案一:复用初始状态逻辑

修改initialState让它返回新对象,再赋值给formData.value:

function initialState(input) {
  // 生成所有属性为空字符串的新对象
  return Object.fromEntries(Object.keys(input).map(key => [key, ""]));
};

function registerUser (e){
 e.preventDefault();
 // 用新对象替换原value,触发更新
 formData.value = initialState(formData.value);
};

方案二:直接重置为初始对象

如果字段数量少,直接在提交函数里写初始对象更简洁:

function registerUser (e){
 e.preventDefault();
 formData.value = { firstName: "", lastName: "" };
};

修正后的完整代码

const formData = signal({ firstName: "", lastName: "" })

const Register = () => {

function setFormData(name, value) {
        return formData.value = {...formData.value, [name]: value};
};

function handleInputChange (e) {
 const { name, value } = e.target;
 setFormData(name, value);
};

function registerUser (e){
 e.preventDefault();
 // 直接替换为新的空对象
 formData.value = { firstName: "", lastName: "" };
};

return(
  <form onSubmit={registerUser}>
   <input
    type="text"
    placeholder="First Name"
    name="firstName"
    value={formData.value.firstName}
    onChange={handleInputChange}
   />
   <input
    type="text"
    placeholder="Last Name"
    name="lastName"
    value={formData.value.lastName}
    onChange={handleInputChange}
   />
   <button>Submit</button>
  </form>
)
}

这样修改后,点击提交按钮时formData.value会被替换成新的空对象,Signal立刻感知到引用变化,触发组件重渲染,输入字段就会同步清空了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 05:07:42