如何在Formik表单提交时获取DropDown子组件的选中值?
问题解决:Formik中自定义DropDown组件值同步方案
你的问题核心是自定义DropDown组件维护了独立内部状态,没有和Formik的全局状态联动,导致提交时Formik无法获取到选中的siteID值。下面提供两种实用的解决方法:
方案一:通过Props传递Formik状态与方法
直接将Formik的value和handleChange传递给DropDown组件,让子组件的选中操作同步更新Formik的值。
修改DropDown组件
import * as React from 'react'; import {StyleSheet} from 'react-native'; import DropDownPicker from 'react-native-dropdown-picker'; import {usePostRequest} from '../../client'; import {useEffect, useState} from 'react'; // 接收外部传入的value、onChange、name参数 const DropDown = ({ value, onChange, name }) => { const [pickeropen, pickersetOpen] = useState(false); const [pickeritems, pickersetItems] = useState([]); const {status: siteStatus, data: siteData} = usePostRequest('/api/sites', {}); useEffect(() => { if (siteData?.count) { const sitesList = siteData.results.map(item => ({ label: item.siteName, value: item.siteID })); pickersetItems(sitesList); } }, [siteData]); // 选择变化时调用Formik的handleChange更新全局状态 const handleSelect = (newValue) => { onChange(name, newValue); }; return ( <DropDownPicker style={styles.textInput} placeholder="Please chose a site" open={pickeropen} value={value === 0 ? null : value} // 适配初始值0,显示placeholder items={pickeritems} setOpen={pickersetOpen} setValue={handleSelect} setItems={pickersetItems} /> ); };
修改父组件中DropDown的调用
// ... 原有代码不变 <DropDown name="siteID" value={values.siteID} onChange={handleChange} /> // ...
方案二:使用Formik的Field组件封装(推荐)
利用Formik的Field组件自动传递表单状态与方法,更符合Formik的最佳实践。
修改DropDown组件适配Field
import * as React from 'react'; import {StyleSheet} from 'react-native'; import DropDownPicker from 'react-native-dropdown-picker'; import {usePostRequest} from '../../client'; import {useEffect, useState} from 'react'; // 接收Field传递的field和form参数 const DropDown = ({ field: { value, onChange }, form }) => { const [pickeropen, pickersetOpen] = useState(false); const [pickeritems, pickersetItems] = useState([]); const {status: siteStatus, data: siteData} = usePostRequest('/api/sites', {}); useEffect(() => { if (siteData?.count) { const sitesList = siteData.results.map(item => ({ label: item.siteName, value: item.siteID })); pickersetItems(sitesList); } }, [siteData]); const handleSelect = (newValue) => { onChange(newValue); }; return ( <DropDownPicker style={styles.textInput} placeholder="Please chose a site" open={pickeropen} value={value === 0 ? null : value} items={pickeritems} setOpen={pickersetOpen} setValue={handleSelect} setItems={pickersetItems} /> ); };
父组件中使用Field调用DropDown
import { Field } from 'formik'; // ... 原有代码不变 <Field name="siteID" component={DropDown} /> // ...
关键说明
- 两种方案的核心都是取消DropDown内部的独立选中状态,改用Formik的全局状态驱动,确保选中值实时同步到Formik的
values中。 - 针对初始值
siteID: 0,通过value={value === 0 ? null : value}的处理,让DropDown初始时显示placeholder,选中后自动同步正确的siteID值。
内容的提问来源于stack exchange,提问作者WhiteFeather
相关产品推荐
相关产品推荐

