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

React Native Paper TextInput在自定义Modal中输入时出现字符闪烁/消失问题

React Native Paper TextInput在自定义Modal中输入时出现字符闪烁/消失问题

我看到你遇到了TextInput在自定义Modal里输入时字符反复闪烁的问题,结合你的代码和React Native常见的坑,我来帮你分析可能的原因和对应的解决方案:

可能的原因及解决方案

1. 自定义Modal的memo优化导致不必要重渲染

你的CustomModal用了React.memo做性能优化,但默认的浅比较会把每次渲染时生成的新children(也就是包含TextInput的View)判定为不同的props。每次输入字符时,FriendAddModal会因为friendCode状态变化重渲染,生成新的children传给CustomModal,触发CustomModal和内部TextInput的重复渲染,最终导致闪烁。

解决方案:
给TextInput所在的区域做局部渲染隔离,用React.memo包裹成独立组件,减少不必要的重渲染:

// 在FriendAddModal组件内部定义
const FriendCodeInput = memo(({ label, value, onChangeText, colors, t }) => (
  <TextInput
    label={label}
    value={value}
    onChangeText={onChangeText}
    mode="flat"
    style={{ backgroundColor: 'rgba(255, 255, 255, 0.1)', marginHorizontal: 10 }}
    placeholder={t('friendAddModal.friendCodePlaceholder')}
    theme={{
      colors: {
        primary: colors.primary,
        placeholder: colors.text,
        text: colors.text,
      },
      fonts: { regular: { fontFamily: 'Orbitron-ExtraBold' } },
    }}
    autoCapitalize="none"
    autoCorrect={false}
    keyboardType="default"
    left={<TextInput.Icon icon="magnify" color={colors.primary} />}
  />
));

然后在FriendAddModal的return里替换原有TextInput:

<View style={{ paddingVertical: 35 }}>
  <FriendCodeInput
    label={t('friendAddModal.friendCodeLabel')}
    value={friendCode}
    onChangeText={setFriendCode}
    colors={colors}
    t={t}
  />
</View>

2. 自定义字体未预加载导致闪烁

你给TextInput设置了Orbitron-ExtraBold自定义字体,如果字体没有在App启动时预加载,每次输入字符时系统都需要临时加载字体资源,就会出现字符闪烁的情况。

解决方案:
确保自定义字体已正确预加载:

  • 如果是Expo项目,用expo-font和AppLoading预加载:
// App.js中
import { useFonts } from 'expo-font';
import AppLoading from 'expo-app-loading';

export default function App() {
  const [fontsLoaded] = useFonts({
    'Orbitron-ExtraBold': require('./assets/fonts/Orbitron-ExtraBold.ttf'),
  });

  if (!fontsLoaded) {
    return <AppLoading />;
  }

  return <YourRootComponent />;
}
  • 如果是裸React Native项目,把字体文件放到android/app/src/main/assets/fonts和ios/[项目名]/Resources/Fonts目录,配置react-native.config.js后重启项目即可。

3. React Native Paper Modal与自定义动画的冲突

你的CustomModal同时使用了react-native-paper的Modal组件和自定义Animated动画,动画逻辑可能干扰了TextInput的正常渲染,导致状态波动。

解决方案:
简化Modal动画,改用react-native-paper Modal自带的动画:

// 修改CustomModal组件,去掉自定义Animated逻辑
const CustomModal = memo(({ visible, onDismiss, onConfirm, children, title, text, confirmText = 'Confirm', showConfirmButton = false, }) => {
  const { colors } = useTheme();
  const { t } = useTranslation();

  return (
    <Portal>
      <Modal
        visible={visible}
        onDismiss={onDismiss}
        animationType="slide" // 使用自带的滑入动画
        contentContainerStyle={[
          styles.modalContainer,
          { backgroundColor: colors.background },
        ]}
      >
        <View style={styles.content}>
          {title && <Text style={[styles.title, { color: colors.text }]}>{title}</Text>}
          {text && <Text style={[styles.text, { color: colors.text }]}>{text}</Text>}
          {children}
          <View style={styles.buttonContainer}>
            <Button mode="outlined" onPress={onDismiss} style={styles.closeButton} labelStyle={styles.closeButtonLabel}>
              {t('customModal.cancel')}
            </Button>
            {showConfirmButton && (
              <Button mode="contained" onPress={onConfirm} style={styles.confirmButton} labelStyle={styles.confirmButtonLabel}>
                {confirmText}
              </Button>
            )}
          </View>
        </View>
      </Modal>
    </Portal>
  );
});

4. 受控组件状态更新的微小延迟(排查用)

虽然你的受控组件写法是正确的,但可以尝试用函数式更新确保状态的实时性,排查是否是状态更新延迟导致的闪烁:

<TextInput
  // 其他props不变
  onChangeText={(text) => setFriendCode(prev => text)}
/>

排查步骤建议

  1. 先临时去掉自定义字体Orbitron-ExtraBold,如果闪烁消失,说明是字体预加载的问题;
  2. 若字体没问题,再尝试给TextInput做局部memo优化,减少重渲染;
  3. 最后再排查Modal动画的冲突问题。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 11:18:06