如何修改代码将Chakra下拉框选中值传递至React表单全局状态
问题
用React+Chakra UI构建表单下拉组件,希望将下拉选中值同步到表单的mentorInfo状态(对应experience、jobTitle、interests字段),但目前选中值仅能在下拉组件内部打印,无法同步到父组件的mentorInfo中。
当前下拉组件代码:
const FormOption: FC<OptionList> = ({name, values}) => { const [selectedValue, setSelectedValue] = useState(values); const handleChange = (e: ChangeEvent<HTMLSelectElement>) => { let selectedValue = e.target.value; setSelectedValue(selectedValue); console.log(selectedValue); } return ( <> <Select placeholder="Select one option" onChange={handleChange} value={selectedValue}> { LISTS .filter(list => list.name === name) .map((list, idx) => <option key={idx} value={list.values}>{list.values}</option>) } </Select> </> ) }
表单状态及handleChange代码:
let [mentorInfo, setMentorInfo] = useState<MentorInfo>({ role: 'mentor', bio: '', expertise: '', experience: '', jobTitle: '', interests: '', hourlyRate: '', }); const handleChange = ( e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement> ) => setMentorInfo({ ...mentorInfo, [e.target.name]: e.target.value }); console.log(mentorInfo);
补充:下拉选项数据源LISTS结构:
export const LISTS = [ { name: "experience", values: "0-2 years", }, { name: "experience", values: "2-4 years", }, { name: "experience", values: "10+ years", }, { name: "jobTitle", values: "Unemployed/ Non-Tech", }, ]
解决方案
核心是把下拉组件改成受控组件,去掉子组件内部的状态,直接复用父组件的mentorInfo状态和handleChange方法:
1. 修改FormOption组件
移除子组件内部的useState,改为接收父组件传入的value和onChange回调,同时给Select加上name属性(让父组件的handleChange能通过e.target.name识别对应字段):
interface OptionListProps { name: string; value: string; // 接收父组件的字段值 onChange: (e: ChangeEvent<HTMLSelectElement>) => void; // 接收父组件的回调 } const FormOption: FC<OptionListProps> = ({ name, value, onChange }) => { return ( <> <Select placeholder="Select one option" onChange={onChange} value={value} name={name} // 必须设置,对应mentorInfo的字段名 > {LISTS .filter(list => list.name === name) .map((list, idx) => ( <option key={idx} value={list.values}> {list.values} </option> ))} </Select> </> ); };
2. 在父组件中使用FormOption
传入对应字段的value(来自mentorInfo)和父组件的handleChange:
// 父组件表单中渲染下拉组件 <FormOption name="experience" value={mentorInfo.experience} onChange={handleChange} /> <FormOption name="jobTitle" value={mentorInfo.jobTitle} onChange={handleChange} /> <FormOption name="interests" value={mentorInfo.interests} onChange={handleChange} />
原理说明
- 子组件不再维护自身状态,完全由父组件的
mentorInfo控制选中值,实现状态统一 Select的name属性对应mentorInfo的字段名,父组件的handleChange通过[e.target.name]动态更新对应字段- 父组件的
handleChange已经支持HTMLSelectElement类型,无需额外修改
内容的提问来源于stack exchange,提问作者ifsm
相关产品推荐
相关产品推荐

