React函数组件如何复用单个onChange函数动态更新多状态(遵循DRY原则)
解决方案
有两种常用实现方式,你可以根据自身需求选择:
方案1:合并状态为单个对象(推荐,更贴近类组件使用习惯)
这种方案把所有表单相关状态存在同一个state对象里,逻辑和类组件的setState几乎一致,后期新增字段只需要在state里加对应属性即可,维护成本更低。
import { useState } from 'react'; function Form(){ // 合并所有表单状态到单个对象 const [formState, setFormState] = useState({ selectedClient: null, selectedLocation: null }); // 统一的onChange处理函数 const handleInputChange = (e) => { const { name, value } = e.target; // 扩展运算符保留原有状态,动态更新对应name的属性 setFormState(prevState => ({ ...prevState, [name]: value })); }; return( <> <input value={formState.selectedClient || ''} id="selectedClient" name="selectedClient" onChange={handleInputChange} /> <input value={formState.selectedLocation || ''} id="selectedLocation" name="selectedLocation" onChange={handleInputChange} /> </> ); }
方案2:保留原有分散的state定义
如果你不想修改现有状态的拆分方式,可以通过映射表匹配name对应的更新函数实现需求:
import { useState } from 'react'; function Form(){ const [selectedClient, updateSelectedClient] = useState(null); const [selectedLocation, updateSelectedLocation] = useState(null); // 建立name和更新函数的映射关系 const stateUpdaterMap = { selectedClient: updateSelectedClient, selectedLocation: updateSelectedLocation }; const handleInputChange = (e) => { const { name, value } = e.target; // 匹配到对应更新函数后执行 const updater = stateUpdaterMap[name]; if (updater) updater(value); }; return( <> <input value={selectedClient || ''} id="selectedClient" name="selectedClient" onChange={handleInputChange} /> <input value={selectedLocation || ''} id="selectedLocation" name="selectedLocation" onChange={handleInputChange} /> </> ); }
注:
value后加|| ''是为了避免值为null时,React将受控组件识别为非受控组件的警告。
内容的提问来源于stack exchange,提问作者mg2019
相关产品推荐
相关产品推荐

