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

React Native函数组件中如何向TextInput追加特殊字符?

React Native函数组件实现TextInput追加特殊字符的解决方法

问题核心

你当前代码的主要问题是混淆了函数组件和类组件的写法,导致TextInput无法正确显示追加的特殊字符:

  • 函数组件中不能用this来获取组件引用,需要用useRef钩子
  • 点击特殊字符按钮时直接覆盖了原有文本,而非追加
  • 多余的addTextInput函数是类组件的写法,完全没必要

解决步骤

  1. 用useRef管理TextInput引用:替换类组件式的this.textInput
  2. 实现字符追加逻辑:使用onChangeSearch的函数式更新,将新字符追加到原有文本后
  3. 清理无用代码:移除addTextInput函数,修正清空按钮的逻辑
  4. 修复搜索过滤逻辑:原useEffect中直接过滤filteredData会导致初始数据异常,改为从原始数据源ALLDATA过滤

修改后的完整代码

import { useState, useEffect, useRef } from 'react';
import { View, Text, TextInput, TouchableOpacity, Pressable, ScrollView, SafeAreaView, FlatList } from 'react-native';
import { Fontisto } from '@expo/vector-icons';
import { Card } from 'react-native-paper';

function SearchScreen({ navigation }) {
  const ALLDATA = WordData;
  const DATA = OnlyWords;
  const ENGDATA = OnlyEngWords;
  const [searchText, onChangeSearch] = useState('');
  const [filteredData, setFilteredData] = useState(ALLDATA);
  const textInputRef = useRef(null);

  useEffect(() => {
    if (searchText === '') {
      setFilteredData(ALLDATA);
      return;
    }
    const filtered = ALLDATA.filter((item) =>
      item.lexical.toLowerCase().includes(searchText.toLowerCase())
    );
    setFilteredData(filtered);
  }, [searchText]);

  const Item = ({ lexical }) => (
    <View style={styles.item}>
      <Text>{lexical}</Text>
    </View>
  );

  const renderItem = ({ item }) => (
    <TouchableOpacity
      onPress={() =>
        navigation.navigate({
          name: 'Results',
          params: { post: item.lexical },
        })
      }
    >
      <Item lexical={item.lexical} />
    </TouchableOpacity>
  );

  return (
    <ScrollView style={styles.scrollView}>
      <Card style={{ justifyContent: 'center', alignItems: 'center' }}>
        <SafeAreaView style={styles.container}>
          <View style={styles.row1}>
            <Pressable
              style={styles.button}
              onPress={() => setFilteredData(DATA)}
            >
              <Text style={styles.text}>Choctaw</Text>
            </Pressable>
            <Pressable
              style={styles.button}
              onPress={() => setFilteredData(ALLDATA)}
            >
              <Text style={styles.text}>All</Text>
            </Pressable>
            <Pressable
              style={styles.button}
              onPress={() => setFilteredData(ENGDATA)}
            >
              <Text style={styles.text}>English</Text>
            </Pressable>
          </View>
          <View>
            <View style={styles.row}>
              <TextInput
                style={{
                  alignItems: 'center',
                  height: 50,
                  borderColor: '#919191',
                  borderWidth: 1,
                  margin: 10,
                  paddingLeft: 15,
                  paddingRight: 15,
                  borderRadius: 10,
                }}
                ref={textInputRef}
                onChangeText={(newText) => onChangeSearch(newText)}
                value={searchText}
                placeholder="Enter Word to Search"
              />
              <TouchableOpacity
                onPress={() => {
                  onChangeSearch('');
                  textInputRef.current?.clear();
                }}
              >
                <Fontisto name="close" size={24} color="green" />
              </TouchableOpacity>
            </View>

            <View style={styles.row1}>
              <TouchableOpacity
                style={styles.button}
                onPress={() => onChangeSearch(prev => prev + 'a̱')}
              >
                <Text style={styles.text}>a̱</Text>
              </TouchableOpacity>
              <TouchableOpacity
                style={styles.button}
                onPress={() => onChangeSearch(prev => prev + 'i̱')}
              >
                <Text style={styles.text}>i̱</Text>
              </TouchableOpacity>
              <TouchableOpacity
                style={styles.button}
                onPress={() => onChangeSearch(prev => prev + 'o̱')}
              >
                <Text style={styles.text}>o̱</Text>
              </TouchableOpacity>
            </View>
            <FlatList
              data={filteredData}
              renderItem={renderItem}
              keyExtractor={(item, index) => item.key || index.toString()}
            />
          </View>
        </SafeAreaView>
      </Card>
    </ScrollView>
  );
}

const styles = {
  scrollView: { flex: 1 },
  container: { flex: 1, padding: 10 },
  row1: { flexDirection: 'row', justifyContent: 'space-around', marginVertical: 10 },
  button: { padding: 10, backgroundColor: '#e0e0e0', borderRadius: 5 },
  text: { fontSize: 16 },
  row: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between' },
  item: { padding: 15, borderBottomWidth: 1, borderBottomColor: '#eee' },
};

export default SearchScreen;

关键说明

  • 受控组件绑定:TextInput必须绑定value={searchText},确保输入框内容和状态完全同步
  • 函数式更新:onChangeSearch(prev => prev + '特殊字符')可以安全获取上一次的状态值,避免状态更新依赖问题
  • useRef使用:textInputRef.current可以直接访问TextInput实例,调用clear()方法(可选,因为清空状态后输入框也会同步清空)

内容的提问来源于stack exchange,提问作者lb594022

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 12:04:51