如何使用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
相关产品推荐
相关产品推荐

