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

如何在React Native TextInput中实现不丢失焦点的清除按钮?

解决React Native TextInput清除按钮触发onBlur导致清空失效的问题

问题核心:点击清除按钮时,系统判定为点击输入框外部,触发onBlur事件将focused设为false,导致清除按钮被隐藏,清空逻辑无法完整执行,同时输入框丢失焦点。

解决方案

通过添加状态标记区分清除操作和正常失焦,确保清空逻辑执行且输入框保持焦点:

  1. 添加状态变量标记清除操作
  2. 修改onBlur逻辑,忽略清除操作触发的失焦
  3. 在清除按钮的点击事件中,执行清空并立即重新聚焦输入框

修改后的完整代码

import {
  View,
  TextInput,
  Pressable,
  Image,
  Text,
} from 'react-native';
import React, {Dispatch, SetStateAction, useRef, useState} from 'react';
import styles from './InputField.styles';
import {useTheme} from 'react-native-paper';
import assets from '@common/assets';
import {layouts} from '@common/constants';

type Props = {
  title?: string;
  icon?: string;
  placeholder?: string;
  isInvalid?: boolean;
  caption?: string;
  value: string;
  valueSetter: Dispatch<SetStateAction<string>>;
  disabled?: boolean;
  autoFill?: boolean;
};

export default function InputField({
  title,
  icon,
  placeholder,
  isInvalid,
  value,
  valueSetter,
  caption,
  disabled = false,
  autoFill = false,
}: Props) {
  const theme = useTheme();
  const [focused, setFocused] = useState(false);
  const [isClearing, setIsClearing] = useState(false); // 新增状态标记清除操作
  const inputRef = useRef<TextInput>(null);

  return (
    <View>
      <Pressable style={styles(theme).mainContainer}>
        <Text style={styles(theme, focused, disabled).title}>{title}</Text>
        <View style={styles(theme, focused, disabled, isInvalid).contentStyle}>
          {icon && (
            <Image
              style={styles(theme).imgContainer}
              resizeMethod="resize"
              source={assets.PersonImage}
            />
          )}
          <TextInput
            editable={!disabled}
            selectionColor={theme.neutralGray1}
            value={value}
            onChangeText={valueSetter}
            onFocus={() => setFocused(true)}
            onBlur={() => {
              // 仅当不是清除操作时,才取消聚焦状态
              if (!isClearing) {
                setFocused(false);
              }
            }}
            style={styles(theme, focused, disabled, isInvalid).inputField}
            placeholder={placeholder}
            ref={inputRef}
          />
          {focused && (
            <Pressable
              onPress={() => {
                setIsClearing(true);
                valueSetter(''); // 清空输入框
                inputRef.current?.focus(); // 立即重新聚焦
                // 延迟重置标记,确保onBlur逻辑执行完毕
                setTimeout(() => setIsClearing(false), 50);
              }}>
              <Image style={{...layouts.ms.lg}} source={assets.InputClear} />
            </Pressable>
          )}
        </View>
        {caption && (
          <Text
            style={
              isInvalid
                ? styles(theme, focused, disabled).invalidCaption
                : styles(theme, focused, disabled).caption
            }>
            {caption}
          </Text>
        )}
      </Pressable>
    </View>
  );
}

关键修改点说明

  • isClearing状态:标记当前是否正在执行清除操作,避免点击清除按钮时触发的onBlur修改focused状态
  • onBlur逻辑优化:只有在非清除操作时才将focused设为false,保证清除按钮不会被立即隐藏
  • 清除按钮点击事件:执行清空后立即调用inputRef.current?.focus()保持输入框焦点,通过短延迟重置isClearing,确保后续正常失焦逻辑不受影响

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 10:33:11