React Native中点击Pressable搜索结果时,如何避免收起键盘?
解决React Native搜索页跳转与键盘收起冲突的方案
你的问题核心是点击搜索结果时,键盘收起触发了keyboardDidHide事件里的返回逻辑,打断了页面跳转。下面是几种实用的解决方法:
方法一:用标志位区分触发场景
添加一个状态变量标记是否正在执行跳转操作,在键盘收起事件里判断是否需要执行返回:
const Search: FC = () => { const navigation = useNavigation(); const [inputText, setInputText] = useState(''); const _inputText = useDeferredValue(inputText); const [searchResult] = useSearchItem(_inputText); // 添加标志位标记是否正在跳转 const [isNavigating, setIsNavigating] = useState(false); useEffect(() => { const keyboardHideSubscription = Keyboard.addListener( 'keyboardDidHide', () => { // 只有非跳转场景才执行返回 if (!isNavigating) { navigation.goBack(); } }, ); return () => { keyboardHideSubscription.remove(); }; }, [isNavigating]); // 依赖标志位变化 return ( <View> <View> <View> <ScrollView showsVerticalScrollIndicator={false}> {searchResult.map(result => ( <Fragment key={result.id}> <List.ItemContent onPress={() => { // 标记为正在跳转 setIsNavigating(true); navigation.navigate('Detail', { itemDetail: result, }); // 跳转后延迟重置标志位,避免影响后续的键盘收起逻辑 setTimeout(() => setIsNavigating(false), 500); }}> <Text>{result.name}</Text> </List.ItemContent> </Fragment> ))} </ScrollView> </View> </View> <KeyboardAvoidingView behavior="padding"> <Shadow> <View> <SearchInput autoFocus value={inputText} onChange={setInputText} /> </View> </Shadow> </KeyboardAvoidingView> </View> ); };
方法二:点击时手动保持输入框焦点(不推荐,体验略差)
如果一定要阻止键盘收起,可以在点击搜索结果时强制让输入框保持焦点,但这种方法可能导致用户跳转后键盘还在,体验不太友好:
// 先给SearchInput加ref const inputRef = useRef<TextInput>(null); // 点击时调用focus <List.ItemContent onPress={() => { inputRef.current?.focus(); navigation.navigate('Detail', { itemDetail: result, }); }}> <Text>{result.name}</Text> </List.ItemContent> // SearchInput组件绑定ref <SearchInput ref={inputRef} autoFocus value={inputText} onChange={setInputText} />
方法三:跳转前临时移除键盘监听
在点击搜索结果时先移除键盘收起的监听,跳转完成后再重新添加:
const Search: FC = () => { const navigation = useNavigation(); const [inputText, setInputText] = useState(''); const _inputText = useDeferredValue(inputText); const [searchResult] = useSearchItem(_inputText); let keyboardHideSubscription: any; useEffect(() => { subscribeKeyboardHide(); return () => { keyboardHideSubscription?.remove(); }; }, []); const subscribeKeyboardHide = () => { keyboardHideSubscription = Keyboard.addListener( 'keyboardDidHide', () => { navigation.goBack(); }, ); }; return ( <View> {/* ...其他代码 */} <List.ItemContent onPress={() => { // 移除监听 keyboardHideSubscription?.remove(); navigation.navigate('Detail', { itemDetail: result, }); // 如果需要在返回搜索页时重新监听,可以在导航回调里处理 navigation.addListener('focus', () => { subscribeKeyboardHide(); }); }}> <Text>{result.name}</Text> </List.ItemContent> {/* ...其他代码 */} </View> ); };
最推荐第一种方法,逻辑清晰且不影响用户体验。
内容的提问来源于stack exchange,提问作者Elton11220
相关产品推荐
相关产品推荐

