You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 23:35:24