React+TypeScript表单优化:避免重复编写状态更新逻辑
优化React表单重复onChange逻辑的几种优雅方式
针对你当前表单里两个输入框onChange逻辑高度重复的问题,有两种常用的优雅解决思路:
1. 合并状态为单个对象,使用通用change处理器
把分散的两个状态合并成一个对象,然后写一个通用的handleChange函数,通过输入框的name属性来对应更新状态中的字段,避免重复编写onChange逻辑。
修改后的代码如下:
function ControlGroup(props: ControlGroupProps) { // 合并状态为单个对象 const [formData, setFormData] = useState({ agentSettings: "", agentQuestion: "" }); // 通用change处理器 const handleChange = ({ target: { name, value } }) => { setFormData(prev => ({ ...prev, [name]: value })); }; return ( <Form onSubmit={(event) => props.onAskAgent(props.agentData, formData.agentSettings, formData.agentQuestion, event) } > <Form.Group className="mb-3" controlId="agentForm.settings"> <Form.Label>Set your agent settings</Form.Label> <Form.Control as="textarea" rows={3} name="agentSettings" // 添加name属性对应状态字段 onChange={handleChange} value={formData.agentSettings} /> </Form.Group> <Form.Group className="mb-3" controlId="agentForm.question"> <Form.Label> Ask your question </Form.Label> <Form.Control as="textarea" rows={3} name="agentQuestion" // 添加name属性对应状态字段 onChange={handleChange} value={formData.agentQuestion} /> </Form.Group> <Button className="center" type="submit"> Ask agent </Button> </Form> ); }
2. 提取复用的子组件
如果表单里有多个结构相似的输入框,可以把重复的Form.Group部分提取成独立的子组件,进一步减少代码冗余。
首先定义复用的子组件:
interface TextareaFieldProps { label: string; controlId: string; name: string; value: string; onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void; rows?: number; } function TextareaField({ label, controlId, name, value, onChange, rows = 3 }: TextareaFieldProps) { return ( <Form.Group className="mb-3" controlId={controlId}> <Form.Label>{label}</Form.Label> <Form.Control as="textarea" rows={rows} name={name} onChange={onChange} value={value} /> </Form.Group> ); }
然后在父组件中复用这个子组件:
function ControlGroup(props: ControlGroupProps) { const [formData, setFormData] = useState({ agentSettings: "", agentQuestion: "" }); const handleChange = ({ target: { name, value } }) => { setFormData(prev => ({ ...prev, [name]: value })); }; return ( <Form onSubmit={(event) => props.onAskAgent(props.agentData, formData.agentSettings, formData.agentQuestion, event) } > <TextareaField label="Set your agent settings" controlId="agentForm.settings" name="agentSettings" value={formData.agentSettings} onChange={handleChange} /> <TextareaField label="Ask your question" controlId="agentForm.question" name="agentQuestion" value={formData.agentQuestion} onChange={handleChange} /> <Button className="center" type="submit"> Ask agent </Button> </Form> ); }
这两种方案都能有效消除重复代码:第一种适合表单字段不多的场景,代码改动小;第二种适合表单包含大量相似输入组件的场景,扩展性更好。
内容的提问来源于stack exchange,提问作者user1357015
相关产品推荐
相关产品推荐

