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

React Native Expo第二个产品Name Input键盘闪烁失焦问题求助

问题解决:React Native Expo输入框点击后键盘闪烁失焦

问题原因

  1. NameInput组件无缓存机制:该组件未用memo包裹,父组件(ProductListItem)因列表更新重渲染时,NameInput会被重新创建,直接导致输入框丢失焦点。
  2. FlatList键值不稳定:keyExtractor依赖item.name生成键值,但新添加的产品name为空,生成的键值(如-1)在布局变化时可能引发组件卸载/重挂载,进一步加剧焦点丢失问题。
  3. 先点击QtyInput无问题的原因:QtyInput已用memo包裹,键盘弹出后布局稳定,后续切换输入框时不会触发破坏性重渲染。

解决方案

1. 给NameInput添加memo缓存

修改NameInput.tsx,用memo包裹组件,避免不必要的重渲染:

import React, { useState, memo } from "react";
import { ActivityIndicator, Text, TextInput, View } from "react-native";
import {
  AntDesign as AntIcon,
  MaterialIcons as MatIcon,
} from "@expo/vector-icons";
import { OrderProductNameValidationStatus } from "@app/types";
import { fakeApiValidateProduct } from "@app/apis";

interface Props {
  shopId: number;
  prodIndex: number;
  prodName: string;
  prodValidation: OrderProductNameValidationStatus;
  unselectNameInput: (
    text: string,
    index: number,
    status: OrderProductNameValidationStatus
  ) => Promise<void>;
}

function NameInput({
  shopId,
  prodIndex,
  prodName,
  prodValidation,
  unselectNameInput,
}: Props): JSX.Element {
  // 组件原有逻辑不变
}

export default memo(NameInput);

2. 优化FlatList的键值生成逻辑

修改ProductsList.tsx的keyExtractor,使用更稳定的标识(如结合索引):

<FlatList
  data={products}
  renderItem={({ item, index }) => (
    <ProductListItem {...props} prodIndex={index} product={item} />
  )}
  keyExtractor={(item, index) => `product-${index}`}
/>

如果业务允许,建议给OrderProduct类型添加唯一id字段,用item.id作为键值的核心部分,进一步提升稳定性。

3. 可选:优化列表更新时机

在Products.tsx的unselectNameInput函数中,可添加判断,避免重复添加空产品:

if (
  status === "success" &&
  updatedProducts[updatedProducts.length - 1].name.length === 0
) {
  updatedProducts.push(copyByValue(newProduct));
}

确保只有最后一个产品已填写时才添加新条目,减少不必要的列表更新次数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 14:35:46