为什么Sharetribe的FieldSelect返回字符串而FieldCheckbox返回对象,如何让FieldSelect存储JSON对象
问题产生原因
- 原生HTML的
<select>元素的<option>仅支持字符串类型的value属性,若传入JSON对象,浏览器会自动调用toString()方法将其转为[object Object]这类无效字符串,因此你当前使用的FieldSelect组件默认返回字符串类型值。 - FieldCheckbox能返回JSON对象,是因为react-final-form对checkbox类型的表单字段做了特殊处理,传入的
value会被原样存储在表单状态中,不会被原生DOM强制转换为字符串。
实现FieldSelect存储JSON对象的方案
方案1:无需修改组件源码,直接在调用时处理(推荐新手使用)
利用react-final-formField组件自带的parse属性,结合JSON序列化/反序列化实现,改动最小:
// 调用代码调整 <FieldSelect name={subGroupCategoryKey} id={subGroupCategoryKey} label={categoryLabel} parse={(value) => value ? JSON.parse(value) : null} > {relevantSubGroupCategoryOptions.map(c => ( <option key={c.key} value={JSON.stringify(c)}> {c.label} </option> ))} </FieldSelect>
拿到表单值时,对应字段已经是完整的JSON对象,无需额外处理。
方案2:改造FieldSelect组件,内置对象值支持
如果需要在多个地方使用该能力,可直接改造组件源码:
- 给FieldSelectComponent新增
options属性,接收完整的选项数组 - 拦截
onChange事件,匹配选中值对应的完整对象后再提交给表单
改造后的核心代码示例:
// FieldSelectComponent内部修改 const FieldSelectComponent = props => { const { rootClassName, className, id, label, input, meta, children, options, ...rest } = props; // 原有逻辑保留... const selectProps = { className: selectClasses, id, ...input, ...rest, onChange: (e) => { const selectedValue = e.target.value; // 匹配完整对象 const selectedOption = options?.find(opt => opt.key === selectedValue); input.onChange(selectedOption || selectedValue); } }; // 原有return逻辑保留... }; // 调用时传入options即可 <FieldSelect name={subGroupCategoryKey} id={subGroupCategoryKey} label={categoryLabel} options={relevantSubGroupCategoryOptions} > {relevantSubGroupCategoryOptions.map(c => ( <option key={c.key} value={c.key}> {c.label} </option> ))} </FieldSelect>
内容的提问来源于stack exchange,提问作者Laveen Ren
相关产品推荐
相关产品推荐

