求助: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, }, });
关键修改点
- 移除独立的
value状态,直接绑定Formik的values.Size到Dropdown的value属性 - 用Formik的
setFieldValue替代setValue,确保选择值同步到表单状态 - 删除冲突的
onChangeText属性,仅保留onChange回调 - 更新标签显示逻辑,改用
values.Size判断是否显示标签
修改后提交表单时即可正确获取Dropdown选择的Size值,同时保留原有UI交互效果。
内容的提问来源于stack exchange,提问作者jo300
相关产品推荐
相关产品推荐

