Search code examples
javascriptreactjsfor-loopreturnrender

How to render a dynamic form in React


I am trying to render a dynamic form to the user. I am using react js. Here is my logic: I first display a number selector and a button to the user. The user has 1 - 10 to choose from with the number selector. After they choose their number, they click the button and what is SUPPOSED to happen is I want the page to render a form with the number of input fields as the selected number from the number selector, as chosen by the user. I wanted to return the input fields in a for loop. However, the

console.log(allTerms);

only prints out twice, and I only get one input field displayed on the page. It seems the loop is getting stuck as it tries to render the second input field. Here is my react component:

import React, { Component } from 'react'

export class ShowTerms extends Component {
    state = {
        numberOfTerms: '0',
        addTerms: false
    }

    addTerms = (event) => {
        event.preventDefault();
        this.setState({addTerms: true});
    }

    onChange = (event) => this.setState({ [event.target.name]: event.target.value});

    render() {
        if(this.state.addTerms === false) {
        return(
            <div>
            <h2>Choose how many terms you wish to add:</h2>
            <input type="number" name="numberOfTerms" min="1" max="10" value={this.state.numberOfTerms} onChange={this.onChange} required></input>
            <input type="button" onClick={this.addTerms}></input>
            </div>
        )
        } else if(this.state.addTerms === true) {
        var allTerms = this.state.numberOfTerms;
            for (var i = 0; i < allTerms; i++) {
                console.log(allTerms);
                return (
                    <div>
                    <input type="text" value="this is a test"></input>
                    </div>
                )  
            }
        } 
    }
}

export default ShowTerms

Any ideas as to why the for loop is only displaying one input field? Is there a mistake in my logic, or would there be a better way to approach displaying this dynamic form? Thanks in advance for any ideas.


Solution

  • You can't use a for loop in a render - it requires a returned expression, not statements like for. So you need to use a map on an array, as per the following:

    const arr = new Array(this.state.numberOfTerms);
    arr.map((i) => (
      <div key={i}>
         <input ...></input>
      </div>));
    

    See https://blog.cloudboost.io/for-loops-in-react-render-no-you-didnt-6c9f4aa73778