Home > Software design >  How to dynamically add Input filed with react hooks state in react native
How to dynamically add Input filed with react hooks state in react native

Time:08-25

My goal is to dynamically add or remove the Input field. I initialize one Input field and then once the user taps the plus icon it should add another field below the first initial field.

This is my sample UI: Here's the actual code in snack add or remove Input fields

And this is my code so far, with function addTextInput.

import {Block, Text, theme} from "galio-framework";
import React, {useEffect, useState} from "react";

export default function SetupLocations({navigation}) {
const [textInput, setTextInput] = useState([]);

const addTextInput = (index) => {
    textInput.push(
        <Block row center space="between" style={{marginTop: 20}} key={index}>
            <Block center>
                <Input
                    onChangeText={(text) => addValues(text, index)}
                    style={styles.input} placeholder={'Your city office name'} iconContent={<Block />}
                />
            </Block>
            <Block right style={{marginLeft: 8}}>
                <Ionicons name="remove-circle" size={18} color="#8898aa"/>
            </Block>
        </Block>
    );
}

return (
    <Block flex style={{ backgroundColor: "#32325d"}}>
        <Block flex>
            <ScrollView>
                <Block middle style={styles.avatarContainer}>
                    <Image
                        source={Images.LoginLogo}
                        style={styles.avatar}
                    />
                </Block>

                <Block style={[styles.details, {backgroundColor: 'white', marginTop: 40}]}>
                    <Block row center space="between" style={{marginTop: 20}}>
                        <Block flex middle center>
                            <Block row style={{textAlign: 'center'}}>
                                <Text color="#32325d" bold>
                                    Set up your locations.
                                </Text>
                            </Block>
                            <Block row style={{textAlign: 'center'}}>
                                <Text color="#36d79a" bold>
                                    You can filter your employee feedback by location.
                                </Text>
                            </Block>
                        </Block>
                    </Block>

                    <Block row center space="between" style={{marginTop: 20}}>
                        <Block center>
                            <Input style={styles.input} placeholder={'Your city office name'} iconContent={<Block />}/>
                        </Block>
                        <Block right style={{marginLeft: 8}}>
                            <Ionicons name="remove-circle" size={18} color="#8898aa"/>
                        </Block>
                    </Block>

                    {!loading ? (
                        <Block>
                            {textInput.map((value) => {
                                return value
                            })}
                        </Block>
                    ) : null}


                    <Block row center space="between" style={{marginTop: 20}}>
                        <Block center>
                            <TouchableOpacity
                                onPress={ () => addTextInput(textInput.length)}
                            >
                                <Ionicons
                                    name="add-circle"
                                    size={18} color="#32325d"
                                />
                            </TouchableOpacity>
                        </Block>
                        <Block right style={{marginLeft: 8}}>
                            <TouchableOpacity
                                onPress={ () => addTextInput(textInput.length)}
                            >
                                <Text muted>Add another location</Text>
                            </TouchableOpacity>
                        </Block>
                    </Block>

                    <Block flex middle center style={{marginTop: 20, marginBottom: 70}}>
                        <Block>
                            <Button color="success" onPress={() => navigation.navigate('CreatePassword')} style={styles.button}>Save my locations</Button>
                        </Block>
                    </Block>
                </Block>
            </ScrollView>
        </Block>
    </Block>
)

This code creates a new field only when I have some changes in code. However, when tapping the "Add another location" it seems like doesn't trigger but when I console.log I can see that the function successfully triggered. Here's the actual code in snack enter image description here

import { View, StyleSheet, TouchableOpacity, ScrollView ,FlatList } from 'react-native';
import Constants from 'expo-constants';
import React, {useEffect, useState} from "react";
import {Block, Input, Text, theme} from "galio-framework";
import Ionicons from "@expo/vector-icons/Ionicons";


export default function App() {
  const [textInput, setTextInput] = useState([]);

  const [textInputMap,setMapInp] = useState([])

  const addTextInput = (index) => {

      const newObject = {
        index:textInputMap.length,
        cityName:`cityName${textInputMap.length}` 
      }

      const alreadyArr = [...textInputMap, newObject]

      setMapInp(alreadyArr)

    }

    const renderEach = ({item,index}) => {
      return(
          <Block row center space="between" style={{marginTop: 20}} key={item.index}>
                <Block center>
                    <Input
                        onChangeText={(text) => addValues(text, item.index)}
                        style={styles.input} placeholder={`your ${item.cityName}`} iconContent={<Block />}
                    />
                </Block>
                <Block right style={{marginLeft: 8}}>
                    <Ionicons name="remove-circle" size={18} color="#8898aa"/>
                </Block>
            </Block>
      )
    }
    const addValues = (text, index) => {
        let dataArray = this.state.inputData;
        let checkBool = false;
        if (dataArray.length !== 0){
            dataArray.forEach(element => {
                if (element.index === index ){
                    element.text = text;
                    checkBool = true;
                }
            });
        }

        if (checkBool){
            setInputData(dataArray)
        }

        else {
            dataArray.push({'text':text,'index':index});
            setInputData(dataArray)
        }
    }

  return (
    <Block flex style={{ backgroundColor: '#32325d'}}>
            <Block flex>
                <ScrollView>
                    <Block style={[styles.details, {backgroundColor: 'white', marginTop: 40}]}>
                        <Block row center space="between" style={{marginTop: 20}}>
                            <Block flex middle center>
                                <Block row style={{textAlign: 'center'}}>
                                    <Text color="#32325d" bold>
                                        Set up your locations.
                                    </Text>
                                </Block>
                                <Block row style={{textAlign: 'center'}}>
                                    <Text color="#36d79a" bold> 
                                        You can filter your employee feedback by location.
                                    </Text>
                                </Block>
                            </Block>
                        </Block>

                        <Block row center space="between" style={{marginTop: 20}}>
                            <Block center>
                                <Input style={styles.input} placeholder={'Your city office name'} iconContent={<Block />}/>
                            </Block>
                            <Block right style={{marginLeft: 8}}>
                                <Ionicons name="remove-circle" size={18} color="#8898aa"/>
                            </Block>
                        </Block>

                        <Block>
                        <FlatList 
                        data={textInputMap}
                        renderItem={renderEach}
                        />
                                {textInput.map((value) => {
                                    return value
                                })}
                            </Block>


                        <Block row center space="between" style={{marginTop: 20}}>
                            <Block center>
                                <TouchableOpacity
                                    onPress={ () => addTextInput(textInput.length)}
                                >
                                    <Ionicons
                                        name="add-circle"
                                        size={18} color="#32325d"
                                    />
                                </TouchableOpacity>
                            </Block>
                            <Block right style={{marginLeft: 8}}>
                                <TouchableOpacity
                                    onPress={ () => addTextInput(textInput.length)}
                                >
                                    <Text muted>Add another location</Text>
                                </TouchableOpacity>
                            </Block>
                        </Block>
                    </Block>
                </ScrollView>
            </Block>
        </Block>
  );
}

const styles = StyleSheet.create({
  container: {
        flex: 1,
        flexDirection: "row",
        alignContent: "space-between",
        justifyContent: "center",
        maxWidth: 500,
        marginBottom: 10
    }
});

Hope it helps , feel free for doubts

  • Related