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

React Native中@ui-kitten/components的Select组件选择卡顿延迟问题

问题根因
  1. 冗余状态导致多次重渲染:你单独维护了selectedIndex本地状态,选中时同时触发本地state更新和Formik的setFieldValue更新,两次状态更新会触发至少两次组件重渲染,若表单整体复杂度高,重渲染耗时会被放大。
  2. 回调函数未做缓存:renderOption方法、label属性的匿名渲染函数每次组件渲染时都会重新生成新的实例,导致Select组件被频繁触发不必要的重渲染。
  3. Formik默认校验机制消耗性能:setFieldValue默认会触发表单全量校验,如果你配置了表单校验规则,每次选中都会跑一次全量校验逻辑,表单字段多的话会产生明显延迟。
  4. 取值逻辑错误(非延迟直接原因但需要修复):setSelectedIndex是异步更新,你紧接着取的displayValue是更新前的旧值,会导致表单提交的语言和实际选中值不一致。
可行优化方案
  • 移除冗余本地状态,直接绑定Formik的值,减少状态更新次数
  • 用useCallback缓存渲染函数和回调,避免不必要的组件重渲染
  • 调用setFieldValue时关闭即时校验,只在提交时触发校验
  • 复杂表单场景下使用Formik的FastField减少跨字段重渲染影响
  • 开发环境debug模式本身存在性能损耗,可打release包确认是否是生产环境也存在延迟,排除debug工具的额外开销影响

优化后代码示例

import { useCallback } from 'react';
import { useFormikContext } from 'formik';
import { Select, SelectItem, Text, IndexPath } from '@ui-kitten/components';

// 常量移到组件外部,避免每次渲染重新生成
const languageData = ['Select language', 'English', 'Hindi'];

// 业务组件内代码
const { values, setFieldValue } = useFormikContext();

// 用useCallback缓存渲染函数
const renderOption = useCallback((title) => <SelectItem title={title} key={title} />, []);
const renderLabel = useCallback((evaProps) => <Text {...evaProps}>Native language</Text>, []);

// 计算当前选中的索引
const selectedIndex = new IndexPath(languageData.findIndex(item => item === values.language));

const handleSelect = useCallback((index) => {
  const selectedLang = languageData[index.row];
  // 第三个参数传false关闭本次更新的校验触发
  setFieldValue('language', selectedLang, false);
}, [setFieldValue]);

// Select组件调用
<Select
  value={values.language}
  selectedIndex={selectedIndex}
  onSelect={handleSelect}
  label={renderLabel}
>
  {languageData.map(renderOption)}
</Select>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 15:54:11