React Native自定义Input组件:无需onFocus/onBlur获取TextInput焦点状态方案
解决React Native自定义Input组件聚焦状态延迟问题
问题原因
直接通过inputRef.current?.isFocused()获取聚焦状态无法实时更新,因为ref的变化不会触发组件重渲染。点击输入框聚焦时,组件没有重新渲染,所以isFocused仍保持旧值;只有当输入内容触发重渲染时,才会重新读取最新的聚焦状态,导致延迟。
解决方案
内部维护聚焦状态,同时兼容用户透传的onFocus/onBlur回调,既不破坏props透传逻辑,又能实时更新状态:
import { useState, PropsWithChildren, useRef } from 'react'; import { TextInput, TextInputProps, View } from 'react-native'; import { ThemeContext } from './your-theme-context-path'; // 替换为实际路径 import useStyles from './your-useStyles-path'; // 替换为实际路径 interface InputProps extends TextInputProps {} export const Input = ({ children, onBlur, onFocus, ...props }: PropsWithChildren<InputProps>) => { const { themeStyles } = useContext(ThemeContext); const { styles } = useStyles(themeStyles); const inputRef = useRef<TextInput>(null); const [isFocused, setIsFocused] = useState(false); // 合并内部状态更新与用户传入的回调 const handleFocus = (...args: Parameters<TextInputProps['onFocus']>) => { setIsFocused(true); onFocus?.(...args); }; const handleBlur = (...args: Parameters<TextInputProps['onBlur']>) => { setIsFocused(false); onBlur?.(...args); }; return ( <View style={[styles.inputContainer]}> <TextInput ref={inputRef} {...props} onFocus={handleFocus} onBlur={handleBlur} style={[styles.input, isFocused && styles.blueText]} > {children} </TextInput> </View> ); };
关键说明
- 通过
useState维护isFocused状态,状态变化会触发组件重渲染,保证UI实时响应聚焦状态。 - 手动合并用户传入的
onFocus/onBlur回调,确保用户透传的逻辑不会被覆盖,完全兼容props透传需求。 - 保留
inputRef,如果需要调用TextInput的其他实例方法(如clear())仍可正常使用。
内容的提问来源于stack exchange,提问作者curious lad
相关产品推荐
相关产品推荐

