Reputation: 625
I have a stateful component that holds some state
state={
name:'',
age:'',
occupation:''
}
And a function to update the state onChange listener
onValueChange = (key, event) => {
this.setState({ [key]: event.target.value });
};
I pass the state and function down to child as props
<ComponentA {...this.state} changed={this.onValueChange}>
Inside my component B which is a child of A I want to programatically create inputs based on given props and change the state by invoking that function every time user types in input.
<ComponentB>
{ Object.entries(this.props)
.filter(
prop =>
prop[0] !== 'changed'
)
.map(propName => (
<Input
key={propName}
label={propName[0]}
value={propName[1]}
onValueChange={this.props.changed(propName[0])}
/>
))}
</ComponentB>
My Input component just renders the following
<input
onChange={this.props.onValueChange}
value={this.props.value}
type={this.props.type}
placeholder=" "
/>
Can't make it work for some reason. Thanks for any help!
Upvotes: 2
Views: 81
Reputation: 112917
You are currently invoking this.props.changed
straight away on render by writing onValueChange={this.props.changed(propName[0])}
. Instead of invoking it on render you should give it a function to call when onValueChange
occurs instead.
You also want to give the Input
a unique key
prop that will not change between state updates, so that React doesn't create an entirely new component every time and you e.g. lose focus of the input
. You can use propName[0]
instead, which will be unique.
<Input
key={propName[0]}
label={propName[0]}
value={propName[1]}
onValueChange={event => this.props.changed(propName[0], event)}
/>
Upvotes: 1