Reputation: 621
I'm trying to make a dynamic input form, which by clicking the button will generate a new row of description input field. I use an array inside the state to keep track of them:
state = {
descriptions: [
{
elementType: 'input',
elementConfig: {
type: 'text',
placeholder: 'Description'
},
value: '',
validation: {
required: true
},
valid: false,
touched: false
}]
}
So in my render method, I use a variable like this to populate my form:
let descriptionsForm = (
<form>
{this.state.descriptions.map((description, index) => (
<Input
key={index}
elementType={description.elementType}
elemenyConfig={description.elementConfig}
value={description.value}
invalid={!description.valid}
shouldValidate={description.validation}
touched={description.touched}
changed={(event) => this.descriptionInputChangedHandler(event, index)}
/>
))}
</form>
<Button btnType={"Success"} clicked={this.pushDescription}>Add Description</Button>
)
This is the pushDescription function:
pushDescription = () => {
var d = {
elementType: 'input',
elementConfig: {
type: 'text',
placeholder: 'Description'
},
value: '',
validation: {
required: true,
isEmail: true
},
valid: false,
touched: false
};
this.state.descriptions.push(d);
console.log(this.state.descriptions);
}
So when I clicked on the "Add Description" button, the console flashes 1 second of the updated descriptions which have 2 elements in it, but soon refreshes to the original state. The website does not change at all.
What am I doing wrong? Any help appreciated.
EDIT: After fixing the form tag problem.Seems like when I type something into the input forms, the newly created forms does show up. Why are they not updating when I click on the button right away?
Thanks for all you guys answering, the working update handler looks like this:
pushDescription = () => {
var d = {
elementType: 'input',
elementConfig: {
type: 'text',
placeholder: 'Description'
},
value: '',
validation: {
required: true,
isEmail: true
},
valid: false,
touched: false
};
let newDescriptions = [
...this.state.descriptions,
d
]
// this.state.descriptions.push(d);
this.setState({ descriptions: newDescriptions})
console.log(this.state.descriptions);
}
Upvotes: 0
Views: 705
Reputation: 1882
it seems like your component is not re-rendering. try
this.setState({ description: this.state.description.push(d) });
this will get your component to re-render as a component re-renders in only following cases:
Upvotes: 2
Reputation: 3487
If you remove <form>
element it would work.
Probably Button
in <form>
element acts like a submit button and refreshes your page.
See this answer to a similar question.
Upvotes: 1
Reputation: 2366
try updating your render method
let descriptionsForm = (
<form>
{this.state.descriptions.map((description, index) => (
<Input
key={index}
elementType={description.elementType}
elemenyConfig={description.elementConfig}
value={description.value}
invalid={!description.valid}
shouldValidate={description.validation}
touched={description.touched}
onChange={(event) => this.descriptionInputChangedHandler(event, index)}
/>
))}
<Button btnType={"Success"} onClick={this.pushDescription}>Add Description</Button>
</form>
)
use 'onClick' rather then 'clicked', and 'onChange' rather than 'changed'
hope it helps :)
Upvotes: 0