Reputation: 57
My program is a modification form.
I want to fill the tag with the value nom of my object: (nom: {id: "1", nom: "ENV"})
So I put in my this.state = {nom: ''}
I fill it with the function:
componentDidMount() {
this.setState(() => ({ nom: this.props.store.environnements.find (p => p.id == this.props.environnement.match.params.id) }));
}
In my render () function, I entered in my value = {this.state.nom.nom} my page it correctly displays the name in the input.
But when I do a refresh, I get an error in the console:
"Uncaught TypeError: Cannot read property 'nom' of undefined at EditEnvironnementForm.render"
Could you help me solve this problem? Thank you!
import React from 'react';
import { connect } from 'react-redux';
export class EditEnvironnementForm extends React.Component {
constructor(props) {
super(props);
this.state = {
nom: '',
error: ''
};
this.onNomChange = this.onNomChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
}
onNomChange(e) {
const nom = e.target.value;
console.log(nom)
this.setState(() => ({ nom: nom }));
}
onSubmit(e) {
e.preventDefault();
if (!this.state.nom) {
this.setState(() => ({ error: 'Please set environnement!' }));
} else {
this.setState(() => ({ error: '' }));
this.props.onSubmitEnvironnement(
{
nom: this.state.nom,
}
);
}
}
componentDidMount() {
this.setState(() => ({ nom: this.props.store.environnements.find (p => p.id == this.props.environnement.match.params.id) }));
}
render() {
return (
<div>
{console.log(this.state.nom)}
{this.state.error && <p className='error'>{this.state.error}</p>}
<form onSubmit={this.onSubmit} className='add-book-form'>
<input type="text" placeholder="nom" autoFocus
value={this.state.nom.nom}
onChange={this.onNomChange} />
<br />
<button>Add Environnement</button>
</form>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
store: state
};
};
export default connect(mapStateToProps)(EditEnvironnementForm);
Upvotes: 2
Views: 738
Reputation: 109
you don,t need to this.setState in componentDidMount its not a good practice if you want to update the state according to the upcoming props then you simple do like that.
componentDidUpdate(prevsProp) {
if (prevsProp.store !== this.props.store){
this.setState({ nom: this.props.store.environnements.find (p => p.id == this.props.environnement.match.params.id) });
}
}
In render method you need to do like this.
<input type="text" placeholder="nom" autoFocus
value={this.state.nom || ''}
onChange={this.onNomChange}
/>
for more information please see the link https://reactjs.org/docs/react-component.html
Upvotes: 1
Reputation: 1794
Render
lifecycle method executes before componentDidMount
.
So in your render
:
<input type="text" placeholder="nom" autoFocus
value={this.state.nom.nom}
onChange={this.onNomChange} />
<br />
this.state.nom
is equal to a string (as you assigned it in the constructor) in the fist render. Then you set the this.state.nom
to object through the componentDidMount
but the first render has already failed and you get the error.
To bypass this you have to check if this.state.nom
is an object. Something like this:
<input type="text" placeholder="nom" autoFocus
value={this.state.nom ? this.state.nom.nom : ''}
onChange={this.onNomChange}
/>
Upvotes: 1