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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 23:43:23