react-nativetextinputreact-native-textinput

Append text to textInput in React Native


I am building an app in React Native where people can search for words. Some of the words have unique characters that people might not know where to access on their phone's keyboards, so I want to include buttons for those characters for ease. I can see that the buttons are updating the filtered list of words when pressed, but I can't get the characters to display in the textInput.

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

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

  const Item = ({ lexical }) => {
    return (
      <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>
  );

  const addTextInput = (key) => {
    let textInput = this.state.textInput;
    textInput.push(<TextInput key={key} />);
    this.setState({ textInput });
    console.log('here');
  };

  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={(input) => {
                  this.textInput = input;
                }}
                onChangeText={(newText) => onChangeSearch(newText)}
                placeholder="Enter Word to Search"
              />
              <TouchableOpacity
                onPress={() => {
                  onChangeSearch('');
                  this.textInput.clear();
                }}>
                <Fontisto name="close" size={24} color="green" />
              </TouchableOpacity>
            </View>

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

I'm not clear on how to access and update the textInput, I can't find the correct documentation or examples in the documentation of how to do this. Currently, the list updates when a button is pressed, I can see the list narrow down only to words with the particular character that was pressed, but the character does not display in the textInput. Is it even possible to append text to textInput in a function (rather than a class)? Many thanks in advance!


Solution

  • You are mixing Class Component syntax into Functional Component syntax, so your function addTextInput() should not work in this case.

    In functional component, we will use hook to handle states change. You can use onChangeSearch() to edit the textInput value.

    Your search text state and hook is defined here.

     //You can access this state value by searchText
     //You can update this state by onChangeSearch()
     const [searchText, onChangeSearch] = useState('');
    

    Replace function addTextInput() with following.

    const addTextInput = (text) => {
      //Edit the searchText by hook with appended text
      onChangeSearch(searchText + text);
    };
    

    And change your textInput, onPress function in the button.

    <TextInput
      style={{
        alignItems: 'center',
        height: 50,
        borderColor: '#919191',
        borderWidth: 1,
        margin: 10,
        paddingLeft: 15,
        paddingRight: 15,
        borderRadius: 10,
      }}
      ref={(input) => {
        this.textInput = input;
      }}
      value={searchText}
      onChangeText={(newText) => onChangeSearch(newText)}
      placeholder="Enter Word to Search"
    />
    
    <TouchableOpacity
      style={styles.button}
      onPress={() => {
          addTextInput('a̱');
      }}
    >
        <Text style={styles.text}>a̱</Text>
    </TouchableOpacity>