I am trying to implement a recursive method on reactjs, but only when data is submitted or clicked.
Following is the code I am trying with:
import React, { Component } from "react";
class Textbox extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {this.setState({value: event.target.value}); }
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<div>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="React" />
</div>
</form>
);
}
}
export default Textbox;
which generates the following view.
I want to use a recursive method onClick or onSubmit, such that it will generate another text box upon submission. Like
which I want to continue until I click some "Exit" or "Stop" button, which I can add to the top of the view.
From what I have read about recursive implementation on ReactJS, I need to call the class/function again inside render. When I do that I think react is getting inside the infinite loop and freezes the browser.
what I tried is to call Textbox inside the <div> <div/> of the render method. Like this:
.... other code lines are same
<div>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="React" />
<Textbox/>
</div>
How can I generate a recursive textbox on submission/clicking event on the previous text box?
You could do it like this, where showNextInput prevents the infinite loop:
class Textbox extends React.Component {
constructor(props) {
super(props);
this.state = {
value: '',
showNextInput: false,
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {this.setState({value: event.target.value}); }
handleSubmit(event) {
console.log('submit');
event.preventDefault();
this.setState({ showNextInput: true });
}
render() {
return (
<>
<form onSubmit={this.handleSubmit}>
<div>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</div>
</form>
{ this.state.showNextInput ? <Textbox/> : null }
</>
);
}
}
However, your use case looks like something you would usually do by
Here a quick and dirty example:
export class TextboxList extends React.Component {
constructor(props) {
super(props);
this.state = {
values: {
0: ''
},
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(index, value) {
this.setState({
values: {
...this.state.values,
[index]: value
}
});
}
handleSubmit(event) {
event.preventDefault();
this.setState({
values: {
...this.state.values,
[Object.keys(this.state.values).length]: '' // add new empty item to list
}
});
}
render() {
return (
<>
<form onSubmit={this.handleSubmit}>
{ Object.keys(this.state.values).map( (index) => {
const value = this.state.values[index];
return <div key={ index }>
<label>
Name:
<input
type="text"
value={ value }
onChange={ (event) => this.handleChange( index, event.target.value ) }
/>
</label>
<input type="submit" value="Submit" />
</div>;
})}
</form>
</>
);
}
}
export default Textbox;