Reputation: 3984
I am trying to create dynamic form, so I pass some jsx elements to a child component as a property. Even though the state is being updated, the updated state is not passed to the element. Below is the code:
This is the child component which maps over the passed controls and outputs them.
class Form extends Component {
render() {
return (
<div>
{this.props.controls.map((c, i) => {
return <React.Fragment key={i}>{c}</React.Fragment>;
})}
</div>
);
}
}
This is the App that calls the child component:
class App extends Component {
constructor(props) {
super(props);
this.state = {
username: '',
password: ''
};
this.controls = [
<input
type="text"
onChange={this.onChangeUsername}
value={this.state.username}
/>
];
}
componentDidUpdate() {
console.log(this.state);
}
render() {
return (
<div className="App">
<div className="app__group">
<h1>This is not working</h1>
<Form controls={this.controls} />
</div>
<div className="app__group">
<h1>This is working</h1>
<input
type="text"
onChange={this.onChangePassword}
value={this.state.password}
/>
</div>
</div>
);
}
onChangeUsername = e => {
console.log('onChangeUsername', e.target.value);
this.setState({ username: e.target.value });
};
onChangePassword = e => {
console.log('onChangePassword');
this.setState({ password: e.target.value });
};
}
As an example of the unexpected behaviour, when an input passed as a property to the child component, I cannot type in the input. The state gets updated but it's is not passed to the child, thus the text does not show.
On the other hand, a standard input element works, I can type and see the output.
What am I doing wrong?
Upvotes: 0
Views: 59
Reputation: 3721
the problem is that you are trying to make something "fixed" as something dynamic. lets go with a more functional approach and it will refresh each one of the inputs like if they are dynamic.
class App extends Component {
constructor(props) {
super(props);
this.state = {
username: '',
password: ''
};
}
componentDidUpdate() {
console.log(this.state);
}
render() {
return (
<div className="App">
<div className="app__group">
<h1>This is not working</h1>
<Form controls={this.controls()} />
</div>
</div>
);
}
controls = () => {
return [<input
type="text"
onChange={this.onChangeUsername}
value={this.state.username}
/>]
}
onChangeUsername = e => {
console.log('onChangeUsername', e.target.value);
this.setState({ username: e.target.value });
};
onChangePassword = e => {
console.log('onChangePassword');
this.setState({ password: e.target.value });
};
}
Upvotes: 3