2

How can I add a text input in React Native with the click of a button? For example, I would press the "+" button and it would add a text input at the bottom of the View.

EDITED: Here is my code (deleted all the irrelevant stuff). Not working for some reason. Clicking the button doesn't do anything.

    import React, { Component, PropTypes } from 'react';
    import { StyleSheet,NavigatorIOS, Text, TextInput, View, Button, 
             TouchableHighlight, TouchableOpacity, ScrollView, findNodeHandle, 
             DatePickerIOS} from 'react-native';
    import TextInputState from 'react-native/lib/TextInputState'

    export default class App extends React.Component {
      constructor(props) {
        super(props);
        this.state = {textInput: [],
          date: new Date(),
        } 
      }

      addTextInput = (key) => {
        let textInput = this.state.textInput;
        textInput.push(<TextInput key={key} />);
        this.setState({ textInput })
      }

      render(){
        return(
          <View>
            <Button title='+' onPress={() => 
               this.addTextInput(this.state.textInput.length)} />
            {this.state.textInput.map((value, index) => {
              return value
            })}
          </View>
        )
      }
    }
2
  • im sorry, but for what you use TextInputState ? Commented Aug 4, 2017 at 6:44
  • I use it to go from one text input to the next when I press the "next" button on the iOS keyboard. In the code that I'm running currently to try to fix this problem, I'm not using it though. Commented Aug 4, 2017 at 6:51

4 Answers 4

7

this is an example for that :

import React, { Component } from 'react';
import { AppRegistry, View, Text, Button, TextInput} from 'react-native';

class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      textInput : []
    }
  }
  addTextInput = (key) => {
    let textInput = this.state.textInput;
    textInput.push(<TextInput key={key} />);
    this.setState({ textInput })
  }
  render(){
    return(
      <View>
        <Button title='+' onPress={() => this.addTextInput(this.state.textInput.length)} />
        {this.state.textInput.map((value, index) => {
          return value
        })}
      </View>
    )
  }
}

maybe that can help you :)

Sign up to request clarification or add additional context in comments.

16 Comments

{this.state.textInput.map((value, index) => { return value })} What is this supposed to mean? It gives me an error on the first line of this block because it's an "invalid left-hand side in arrow function parameters." Also, is there a way to have separate textInput arrays for different views so that when I click on one button, it adds a text input to the outermost view that that specific button is part of?
this.state.textInput is an array for looping <TextInput /> component, map is for looping the component, value is the value in this.state.textInput array, i have try that code first, and works well in my device :)
Sorry for still needing help, I just started learning React Native recently. I commented out all my code and then copy-pasted your answer, and when I ran the app again there's a '+' button at the top center of the screen but it doesn't do anything when I press it.
just posted it in the original question
Basically I want to be able to click on a button and have some View pop up at the bottom of the outer View. For example, the new View could be just a text input or a View containing a DatePicker and a text input.
|
1

I have a solution that begins with a single text input. It has an "add" button that adds another text input just below the first. That new input keeps the "add" button, and all previous inputs above change to a "remove" button, with which, of course, the user can remove the corresponding view. I could only get it to work by handling state in a React Redux store, and so the code is spread out between too many different files to post here, but anyone interested can view it on GitHub or Snack.

I know this is an old post, but this is a problem I wish was answered when I first came here.

2 Comments

How can i handle it if i don't want to use Redux?
I was not able to get it to work without Redux. Maybe if you're a wiz at passing props, you could get it to work, but I could only get it to work with Redux.
0

Here is example of dynamic add remove input

    let obj = { text: '' }
    this.state = {
        attributeForm: [{ [1]: obj }],
        duplicateAttributes: [1]
    }

  addAtributeRow() {
    const { duplicateAttributes, attributeForm } = this.state;
    let pushNumber = 1;
    if (duplicateAttributes.length > 0) {
        let max = Math.max(...duplicateAttributes);
        pushNumber = max + 1
    }
    let arr = duplicateAttributes;
    arr.push(pushNumber)
    let obj = { text: '' }
    this.setState({
        attributeForm: [...attributeForm, { [pushNumber]: obj }]
    })

    this.setState({
        duplicateAttributes: arr
    })
}

  deleteAttributeRow(number) {
    const { duplicateAttributes, attributeForm } = this.state;
    const index = duplicateAttributes.indexOf(number);
    if (index > -1) {
        duplicateAttributes.splice(index, 1);

        let findedIndex;
        for (let i = 0; i < attributeForm.length; i++) {
            // var index = Object.keys(attributeForm[i]).indexOf(index);
            if (Object.keys(attributeForm[i])[0] == number) {
                findedIndex = i;
            }
        }

        if (findedIndex > -1) {
            attributeForm.splice(findedIndex, 1);
        }

    }
    this.setState({
        attributeForm: attributeForm,
        duplicateAttributes: duplicateAttributes
    })
}

  render() {
    const {attributeForm} = this.state;


   
    {
        duplicateAttributes.length > 0 && duplicateAttributes.map((item, index) =>
<View >

        <Item style={GStyle.borderStyle} >
            <Textarea placeholder="Text"
                style={[GStyle.placeholder.text, { width: wp('90%') }]}
                keyboardType="default"
                autoCorrect={true}
                autoCapitalize={'words'}
                rowSpan={4}
                value={attributeForm[index][item]['text']}
                placeholderTextColor={GStyle.placeholder.color}
                onChangeText={(text) => this.addAttributes(item, text, 'text')}
                returnKeyLabel='done'
            />
        </Item>
        <View style={{ flexDirection: 'row', justifyContent: 'space-between', marginHorizontal: wp('30%') }}>
            {
                <Button full rounded onPress={() => { this.deleteAttributeRow(item) }} >
                    <Icon name="minus" type="FontAwesome5" style={{ fontSize: wp('4%') }} />
                </Button>
            }
        </View>
    </View>
    }

   <Button  full rounded onPress={() => { this.addAtributeRow() }} >
                                 <Icon name="plus" type="FontAwesome5" style={{ fontSize: wp('4%') }} /> 
              </Button>
    }

Comments

0

If you want to do this with Hooks or Functional component then here is the link of Expo https://snack.expo.dev/@muhammadabdullahrishi/add-input I have included how to add and delete Text Input

with hooks

2 Comments

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.