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

React Native Picker滚动后复位至第一项且选中值异常(Formik场景)

解决React Native Picker与Formik联动的问题

看起来你遇到的核心问题是Picker的状态没有和Formik的表单状态正确绑定,导致了滚动复位和提交时catalog字段为undefined的问题。我帮你一步步排查并解决:

问题分析

你当前把Picker的选中值存在组件自身的selectedValue状态里,但Formik的表单状态是独立维护的:

  1. 当Formik的表单状态更新(比如其他输入框输入内容),组件会重渲染,Picker的value还是依赖组件自身的selectedValue,如果这个值和Formik的catalog初始值不一致,就可能触发复位。
  2. 提交表单时,Formik只会读取自己管理的字段值,而你没有把Picker的选中值同步到Formik的catalog字段,所以会拿到undefined。
    另外,Picker的height设置为10太小了,这可能导致触摸交互异常,也是滚动后复位的潜在原因。

解决方案:把Picker完全交给Formik管理

我们需要移除组件自身的selectedValue状态,直接让Picker和Formik的表单状态联动:

1. 简化组件State

只保留异步加载的catalogs,去掉selectedValue:

state = {
  catalogs: [],
};

2. 修改Picker组件,绑定Formik的状态和方法

在Formik的渲染回调里,我们可以拿到values(表单当前值)和setFieldValue(更新表单字段的方法),用这两个来控制Picker:

<Picker
  style={{ height: 50, width: 325 }} // 把height调整为合理值,避免交互异常
  value={values.catalog} // 直接绑定Formik的catalog字段值
  mode="dropdown"
  itemStyle={{
    backgroundColor: '#F6F6F6',
    color: 'black',
    height: 120,
    marginTop: 25,
    fontFamily: 'Ebrima',
    fontSize: 17,
    borderRadius: 5,
    borderColor: '#7e2f89',
  }}
  // 用setFieldValue直接更新Formik的catalog字段
  onValueChange={(selectedValue) => setFieldValue('catalog', selectedValue)}
>
  {this.state.catalogs.map((member, key) => (
    <Picker.Item label={member.name} value={member.name} key={key} />
  ))}
</Picker>

3. 确保Formik的渲染回调能拿到所需Props

你的Formik组件需要以render prop的形式传递子组件,这样才能拿到values、setFieldValue和handleSubmit:

<Formik
  initialValues={{
    name: '',
    description: '',
    costPrice: '',
    salePrice: '',
    catalog: '',
    amountStock: '',
  }}
  onSubmit={(values) => {
    // 现在这里的values.catalog就是Picker选中的值了
    console.log('提交的表单值:', values);
    // 执行你的产品注册逻辑
  }}
>
  {/* 这里解构出Formik的核心方法和状态 */}
  {({ values, setFieldValue, handleSubmit }) => (
    <View>
      {/* 其他表单输入组件,比如name、description等 */}
      {/* 上面修改后的Picker组件 */}
      <Button title="注册产品" onPress={handleSubmit} />
    </View>
  )}
</Formik>

可选优化:处理目录加载状态

如果catalogs是异步加载的,建议加个条件渲染避免空Picker:

{this.state.catalogs.length > 0 ? (
  // 上面的Picker组件
) : (
  <Text style={{ padding: 16 }}>正在加载目录...</Text>
)}

这样修改后,Picker的选中状态会完全和Formik的catalog字段同步,滚动时不会再复位,提交表单时也能拿到正确的catalog值了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 21:07:42