0

I'm trying to add a new input on button click in one of my React components. What's the most elegant way to do it?

This is an abstraction of my code:

const addDivs = (type) => { ??? }

export default function Form() {

handleSubmit(e) {...}

return ( 
<form onSubmit={handleSubmit}>
<div><textarea rows="4" placeholder="Write about something here..." /></div>
//New divs should go here

//Adds a textarea
<button onClick={() => addDivs(textarea)}>Add textarea</button>
//Adds an upload field
<button onClick={() => addDivs(upload)}>Add image</button>
<input type="submit" value="Submit" /> </form> ); 
}

I want to keep the buttons underneath the inputs.

How's the best way to do this?

3
  • So you want to insert your divs under the textarea but the button should be directly below the textarea? Commented Dec 29, 2021 at 17:58
  • Does this answer your question? React.js: How to append a component on click? Commented Dec 29, 2021 at 18:12
  • Do you want a new input or a new div? Commented Dec 29, 2021 at 18:15

2 Answers 2

2

My idea is to create 2 states, one for each button, they will have the number of the divs needed for each tag.

const [textAreaNo,setTextAreaNo] = useState(0);
const [uploadNo,setUploadNo] = useState(0);

then after your buttons you can call the (addDiv) function, but u will have to create 2 different functions for each button, or just make one function and inside the function it will return upload or textArea depending on the passed parameter.

then finally you need to use map like this

{[...Array(textAreaNo)].map(e=>(
    <div> textbox <div>
  ))}

and on your button we will just increment the states above like

 <button onClick={()=> setTextAreaNo(textAreaNo+1)}>AddDivs</button>
Sign up to request clarification or add additional context in comments.

Comments

0

I'm not sure if you want to be able to add multiple text areas. A way I would do it, is to create a state item that knows how many text areas you need, and then a function that increases this number on the onClick(). You will also need a function that returns the text box item. Something like this:

Class Component:

this.state = {
    numberOfTextAreas: 0
}

const textAreas = () => { //<---------a function like this

for (let i = 0; i < this.state.numberOfTextAreas; i++) {
    return (
        <div>
           <textarea rows="4" placeholder="Write about sompething here..." /> 
        </div>
    );
}
}

const addDivs = (type) => { ??? }

export default function Form() {

handleSubmit(e) {...}

return ( 
<form onSubmit={handleSubmit}>
<div><textarea rows="4" placeholder="Write about something here..." /></div>


//New divs should go here
{textAreas} //<---- Add this here.


<button onClick={() => this.setState({numberOfTextAreas + 1})}>Add textarea</button>
//Adds an upload field
<button onClick={() => addDivs(upload)}>Add image</button>
<input type="submit" value="Submit" /> </form> ); 
}

```

Then you'll just want to do the same with the other types you are wanting to create.

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.