如何在useReducer Hook中使用内联dispatch实现表单双向绑定
问题
我用useReducer管理表单状态,希望每次按键时实现类似useState的双向绑定来更新表单值。使用外部处理函数时可以正常工作:
const idHandler = (e) => { dispatch({ type: "0", value: e.target.value }); } onChange={idHandler}
但尝试使用内联函数时,无法正确获取event的值,比如这样写会报错找不到e:
onChange={()=>dispatch({ type: "0", value: e.target.value })}
试了this.target.value也无效,完整代码如下:
import "./ProductForm.css"; import { useReducer } from "react"; const ProductForm = () => { const initialState = { product_id: "e11", product_name: "Masti kr ryian", product_quantity: 0, product_description: "", product_type: "", product_valid: "false", product_price: 0, product_title: "", product_image: "", }; const reducer = (state, action) => { if (action.type === "0") { return { product_id: action.value }; } else if (action.type === "1") { return state.product_name; } else { return "Error"; } }; const [state, dispatch] = useReducer(reducer, initialState); return ( <form> <div className="form-group"> <label>Product id</label> <input type="text" className="form-control" value={state.product_id} onChange={() => dispatch({ type: "0", val: event.target.value })} /> </div> <div className="form-group"> <label>Product Name</label> <input type="text" className="form-control" value={state.product_name} // onChange={(e) => dispatch("1")} /> </div> <button type="submit" className="btn btn-primary mt-4"> Submit </button> </form> ); }; export default ProductForm;
解决方法
1. 修正内联函数的event参数传递
内联箭头函数需要显式接收event参数,否则无法访问e.target.value。正确写法:
onChange={(e) => dispatch({ type: "0", value: e.target.value })}
你之前的代码里没有声明e这个参数,导致变量未定义报错。
2. 修复reducer的状态丢失问题
当前reducer每次更新只返回单个属性,会丢失初始状态里的其他字段(比如product_name、product_quantity等)。必须展开原状态,再覆盖需要更新的属性,保证状态的完整性:
const reducer = (state, action) => { switch(action.type) { case "0": return { ...state, product_id: action.value }; case "1": return { ...state, product_name: action.value }; // 后续其他字段的更新case可以按同样方式添加 default: return state; // 默认返回原状态,避免返回错误字符串破坏状态结构 } };
3. 完善第二个输入框的onChange逻辑
第二个输入框需要传递输入值到dispatch,写法和第一个输入框一致:
<input type="text" className="form-control" value={state.product_name} onChange={(e) => dispatch({ type: "1", value: e.target.value })} />
内容的提问来源于stack exchange,提问作者Ayan Khan
相关产品推荐
相关产品推荐

