如何在React Native TextInput中实现不丢失焦点的清除按钮?
解决React Native TextInput清除按钮触发onBlur导致清空失效的问题
问题核心:点击清除按钮时,系统判定为点击输入框外部,触发onBlur事件将focused设为false,导致清除按钮被隐藏,清空逻辑无法完整执行,同时输入框丢失焦点。
解决方案
通过添加状态标记区分清除操作和正常失焦,确保清空逻辑执行且输入框保持焦点:
- 添加状态变量标记清除操作
- 修改
onBlur逻辑,忽略清除操作触发的失焦 - 在清除按钮的点击事件中,执行清空并立即重新聚焦输入框
修改后的完整代码
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
相关产品推荐
相关产品推荐

