React Native小技巧

1、输入框 + clear按钮 不关闭键盘

RN的默认行为: scrollview + textinput + 自定义的清除按钮,输入框获焦的时候 弹起键盘,此时点击清空按钮的时候会先关闭弹框,需要再次点击清除按钮才会清空输入框

观察原生app的输入框可以 点击清空按钮的时候 输入框还是获焦状态 而且键盘没有关闭,然后摸索实现方式。

方式一:失焦再获焦,这样会让键盘有关闭动作再升起来,效果虽然达到了,但是还差一些意思。

ts 复制代码
export default function SearchInput() {
  const [text, setText] = useState('');
  const inputRef = useRef<TextInput>(null);

  const handleClear = () => {
    setText('');
    // 立即重新聚焦
    requestAnimationFrame(() => {
      inputRef.current?.focus();
    });
  };

  return (
    <View style={styles.container}>
      <TextInput ref={inputRef} style={styles.input} value={text} onChangeText={setText} placeholder="输入内容..." />
      {text.length > 0 && (
        <TouchableOpacity
          style={styles.closeButton}
          onPress={handleClear}
          activeOpacity={0.7}
          hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
        >
          <Text style={styles.closeText}>×</Text>
        </TouchableOpacity>
      )}
    </View>
  );
}

方式二:使用react-native-gesture-handler自带的Pressable组件,它运行在原生线程上,不会触发 JS 线程的失焦事件,完美的达到我需要的效果。

ts 复制代码
import React, { useRef, useState } from 'react';
import { StyleSheet, View, TextInput, Text } from 'react-native';
// 主要是这里的 Pressable组件!
import { Pressable } from 'react-native-gesture-handler';

export default function SearchInput() {
  const [text, setText] = useState('');
  const inputRef = useRef<TextInput>(null);

  const handleClear = () => {
    setText('');
  };

  return (
    <View style={styles.container}>
      <TextInput ref={inputRef} style={styles.input} value={text} onChangeText={setText} placeholder="输入内容..." />
      {text.length > 0 && (
        <Pressable
          style={styles.closeButton}
          onPress={handleClear}
          hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
        >
          <Text style={styles.closeText}>×</Text>
        </Pressable>
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: COLORS.white,
    borderRadius: scaleLinear(9),
    paddingHorizontal: scaleLinear(SPACING.md),
    height: scaleLinear(38),
    borderWidth: 1,
    borderColor: COLORS.gray4,
  },
  input: {
    flex: 1,
    fontSize: scaleLinear(14),
    color: COLORS.textPrimary,
    paddingVertical: 0,
  },
  closeButton: {
    width: scaleLinear(24),
    height: scaleLinear(24),
    borderRadius: scaleLinear(12),
    backgroundColor: COLORS.gray1,
    alignItems: 'center',
    justifyContent: 'center',
    marginLeft: scaleLinear(4),
  },
  closeText: {
    fontSize: scaleLinear(16),
    color: COLORS.textSecondary,
    textAlign: 'center',
    lineHeight: scaleLinear(22),
  },
});
相关推荐
程序员爱钓鱼5 小时前
Rust String 与 &str 详解:字符串所有权、借用与转换
前端·后端·rust
码农学院5 小时前
GEO与SEO协同:从传统搜索到生成式搜索的平滑迁移路径
服务器·前端·python
咩咩啃树皮13 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
阳光是sunny13 小时前
LangGraph中的Reducer是什么
前端·人工智能·后端
触底反弹13 小时前
一文搞懂 Tailwind CSS 弹性布局:从原理到实战
前端·css·html
阳光是sunny14 小时前
从链到图:LangGraph 入门基础全解析
前端·人工智能·后端
小林ixn14 小时前
从 ??= 到 onKeyDown:一个 React 组件的“自我修养”
前端·javascript·react.js
REDcker15 小时前
显示分辨率标准对照详解
前端·网络·分辨率·显示·屏幕
এ慕ོ冬℘゜15 小时前
前端实战:jQuery 多条件联合搜索(标题模糊查询 + 日历时间段筛选)
前端·javascript·jquery
武子康15 小时前
Search Console Platform Properties 扩大 SEO 资产边界:从 Page Ranking 到 Topic Coverage(5 类误读边界 + 3 表数据层设计)
前端·人工智能·后端