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

求助:React Native中Formik与react-native-element-dropdown集成问题

React Native中Formik结合react-native-element-dropdown选择器的问题解决

我想在React Native中结合Formik使用react-native-element-dropdown选择器,编写了相关代码但始终无法实现预期效果,以下是我的项目依赖版本和代码,恳请帮忙解决:

项目依赖版本

"dependencies": {
  "expo": "~48.0.18",
  "expo-status-bar": "~1.4.4",
  "formik": "^2.4.2",
  "react": "18.2.0",
  "react-native": "0.71.8",
  "react-native-element-dropdown": "^2.9.0",
  "react-native-gesture-handler": "^2.9.0",
  "react-native-reanimated": "2.14.4",
  "yup": "^1.2.0"
}

原代码

import React, { useState } from 'react';
import { StyleSheet, View } from 'react-native';
import { Button, Text } from 'react-native-elements';
import { Formik } from 'formik';
import { Dropdown } from 'react-native-element-dropdown';

const MyForm = () => {
    const [value, setValue] = useState(null);
    const [isFocus, setIsFocus] = useState(false);

    const data = [
        { label: 'A', value: '0' },
        { label: 'B', value: '1' },
        { label: 'C', value: '2' },
        { label: 'D', value: '3' },
    ]

    const renderLabel = () => {
        if (value || isFocus) {
            return (
                <Text style={[styles.label, isFocus && { color: 'blue' }]}>
                    Size
                </Text>
            );
        }
        return null;
    };
    
    return (
        <Formik
            initialValues={{ Size: '' }}
            onSubmit={(values) => console.log(values)}
        >
            {({ handleSubmit, handleChange}) => (
                <View style={styles.container}>
                    {renderLabel()}
                    <Dropdown
                        style={[styles.dropdown, isFocus && { borderColor: 'blue' }]}
                        placeholderStyle={styles.placeholderStyle}
                        selectedTextStyle={styles.selectedTextStyle}
                        inputSearchStyle={styles.inputSearchStyle}
                        iconStyle={styles.iconStyle}
                        data={data}
                        search
                        maxHeight={300}
                        labelField="label"
                        valueField="value"
                        placeholder={!isFocus ? 'Size' : '...'}
                        searchPlaceholder="Search..."
                        value={value}
                        onChangeText={handleChange}  
                        onFocus={() => setIsFocus(true)}
                        onBlur={() => setIsFocus(false)}
                        onChange={item => {
                            setValue(item.value);
                            setIsFocus(false);
                        }}
                    />
                    <Button title="Submit" onPress={handleSubmit} />
                </View>
            )}
        </Formik>
    );
};

export default MyForm;

const styles = StyleSheet.create({
    container: {
        backgroundColor: 'white',
        padding: 16,
        margin: 10,
    },
    dropdown: {
        height: 50,
        borderColor: 'gray',
        borderWidth: 0.5,
        borderRadius: 8,
        paddingHorizontal: 8,
    },
    icon: {
        marginRight: 5,
    },
    label: {
        position: 'absolute',
        backgroundColor: 'white',
        left: 22,
        top: 8,
        zIndex: 999,
        paddingHorizontal: 8,
        fontSize: 14,
    },
    placeholderStyle: {
        fontSize: 16,
    },
    selectedTextStyle: {
        fontSize: 16,
    },
    iconStyle: {
        width: 20,
        height: 20,
    },
    inputSearchStyle: {
        height: 40,
        fontSize: 16,
    },
});

问题分析

核心问题是没有将Dropdown的选择值同步到Formik的表单状态,而是用独立useState维护value,导致Formik的values.Size始终为空;同时同时设置onChangeText和onChange造成逻辑冲突,react-native-element-dropdown仅需使用onChange回调。

解决方案

去掉独立的value状态,直接绑定Formik的表单状态,用setFieldValue更新选择值,修改后的代码如下:

import React, { useState } from 'react';
import { StyleSheet, View } from 'react-native';
import { Button, Text } from 'react-native-elements';
import { Formik } from 'formik';
import { Dropdown } from 'react-native-element-dropdown';

const MyForm = () => {
    const [isFocus, setIsFocus] = useState(false);

    const data = [
        { label: 'A', value: '0' },
        { label: 'B', value: '1' },
        { label: 'C', value: '2' },
        { label: 'D', value: '3' },
    ]

    return (
        <Formik
            initialValues={{ Size: '' }}
            onSubmit={(values) => console.log(values)}
        >
            {({ handleSubmit, values, setFieldValue}) => {
                const renderLabel = () => {
                    if (values.Size || isFocus) {
                        return (
                            <Text style={[styles.label, isFocus && { color: 'blue' }]}>
                                Size
                            </Text>
                        );
                    }
                    return null;
                };
                
                return (
                    <View style={styles.container}>
                        {renderLabel()}
                        <Dropdown
                            style={[styles.dropdown, isFocus && { borderColor: 'blue' }]}
                            placeholderStyle={styles.placeholderStyle}
                            selectedTextStyle={styles.selectedTextStyle}
                            inputSearchStyle={styles.inputSearchStyle}
                            iconStyle={styles.iconStyle}
                            data={data}
                            search
                            maxHeight={300}
                            labelField="label"
                            valueField="value"
                            placeholder={!isFocus ? 'Size' : '...'}
                            searchPlaceholder="Search..."
                            value={values.Size}
                            onFocus={() => setIsFocus(true)}
                            onBlur={() => setIsFocus(false)}
                            onChange={item => {
                                setFieldValue('Size', item.value);
                                setIsFocus(false);
                            }}
                        />
                        <Button title="Submit" onPress={handleSubmit} />
                    </View>
                )
            }}
        </Formik>
    );
};

export default MyForm;

const styles = StyleSheet.create({
    container: {
        backgroundColor: 'white',
        padding: 16,
        margin: 10,
    },
    dropdown: {
        height: 50,
        borderColor: 'gray',
        borderWidth: 0.5,
        borderRadius: 8,
        paddingHorizontal: 8,
    },
    icon: {
        marginRight: 5,
    },
    label: {
        position: 'absolute',
        backgroundColor: 'white',
        left: 22,
        top: 8,
        zIndex: 999,
        paddingHorizontal: 8,
        fontSize: 14,
    },
    placeholderStyle: {
        fontSize: 16,
    },
    selectedTextStyle: {
        fontSize: 16,
    },
    iconStyle: {
        width: 20,
        height: 20,
    },
    inputSearchStyle: {
        height: 40,
        fontSize: 16,
    },
});

关键修改点

  1. 移除独立的value状态,直接绑定Formik的values.Size到Dropdown的value属性
  2. 用Formik的setFieldValue替代setValue,确保选择值同步到表单状态
  3. 删除冲突的onChangeText属性,仅保留onChange回调
  4. 更新标签显示逻辑,改用values.Size判断是否显示标签

修改后提交表单时即可正确获取Dropdown选择的Size值,同时保留原有UI交互效果。

内容的提问来源于stack exchange,提问作者jo300

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 09:44:54