16

I would like to have an Add input button that, when clicked, will add a new Input component. The following is the React.js code that I thought is one way of implementing the logic that I want, but unfortunately it's doesn't work.

The exception that I got is:

invariant.js:39 Uncaught Invariant Violation: Objects are not valid as a React child (found: object with keys {input}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of FieldMappingAddForm.

How do I solve this problem?

import React from 'react';
import ReactDOM from "react-dom";


class Input extends React.Component {
    render() {
        return (
            <input placeholder="Your input here" />
        );
    }
}


class Form extends React.Component {
    constructor(props) {
        super(props);
        this.state = {inputList: []};
        this.onAddBtnClick = this.onAddBtnClick.bind(this);
    }

    onAddBtnClick(event) {
        const inputList = this.state.inputList;
        this.setState({
            inputList: inputList.concat(<Input key={inputList.length} />)
        });
    }

    render() {
        return (
            <div>
                <button onClick={this.onAddBtnClick}>Add input</button>
                {this.state.inputList.map(function(input, index) {
                    return {input}   
                })}
            </div>
        );
    }
}


ReactDOM.render(
    <Form />,
    document.getElementById("form")
);

3 Answers 3

27

React Hook Version

Click here for live example

import React, { useState } from "react";
import ReactDOM from "react-dom";

const Input = () => {
  return <input placeholder="Your input here" />;
};

const Form = () => {
  const [inputList, setInputList] = useState([]);

  const onAddBtnClick = event => {
    setInputList(inputList.concat(<Input key={inputList.length} />));
  };

  return (
    <div>
      <button onClick={onAddBtnClick}>Add input</button>
      {inputList}
    </div>
  );
};

ReactDOM.render(<Form />, document.getElementById("form"));
Sign up to request clarification or add additional context in comments.

Comments

13

Remove {}., it is not necessary using it in this case

{this.state.inputList.map(function(input, index) {
  return input;
})}

Example

or better in this case avoid .map and just use {this.state.inputList},

Example

Comments

-1
const [visible,setVisible] = useState(false);
return(
    <>
    <button onClick={()=>setVisible(true)}>Hit me to add new div</button>
    {
      visible ? (
        <div id='addThisContainer'>
          {/* Your code inside */}
        </div>
       ) : null
    }
  </>
)

Comments

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.