Mon programme est un formulaire de modification.

Je veux remplir la balise avec la valeur nom de mon objet : (nom : {id : "1", nom : "ENV"})

J'ai donc mis dans mon this.state = {nom: ''}

Je le remplis avec la fonction :

componentDidMount() {
    this.setState(() => ({ nom: this.props.store.environnements.find (p => p.id == this.props.environnement.match.params.id) }));
}

Dans ma fonction render (), j'ai entré dans ma valeur = {this.state.nom.nom} ma page, il affiche correctement le nom dans l'entrée.

Mais quand je fais un rafraîchissement, j'obtiens une erreur dans la console :

"Uncaught TypeError : Impossible de lire la propriété 'nom' d'undefined à EditEnvironnementForm.render"

Pourriez-vous m'aider à résoudre ce problème ? Merci!

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);
2
hulriche 18 mars 2019 à 17:54

2 réponses

Meilleure réponse

Vous n'avez pas besoin de this.setState dans componentDidMount ce n'est pas une bonne pratique si vous voulez mettre à jour l'état en fonction des accessoires à venir, alors faites comme ça.

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) });
    }
}

Dans la méthode de rendu, vous devez faire comme ceci.

<input type="text" placeholder="nom" autoFocus
   value={this.state.nom || ''}
   onChange={this.onNomChange} 
/>

Pour plus d'informations s'il vous plaît voir le lien https://reactjs.org/docs/react-component.html

1
Atiq Ur Rehman 18 mars 2019 à 16:15

La méthode de cycle de vie Render s'exécute avant componentDidMount.

Donc dans votre render :

 <input type="text" placeholder="nom" autoFocus
   value={this.state.nom.nom}
   onChange={this.onNomChange} />
 <br />

this.state.nom est égal à une chaîne (telle que vous l'avez assignée dans le constructeur) dans le premier rendu. Ensuite, vous définissez le this.state.nom pour s'opposer via le componentDidMount mais le premier rendu a déjà échoué et vous obtenez l'erreur. Pour contourner cela, vous devez vérifier si this.state.nom est un objet. Quelque chose comme ça:

<input type="text" placeholder="nom" autoFocus
   value={this.state.nom ? this.state.nom.nom : ''}
   onChange={this.onNomChange} 
/>
1
Vladimir Bogomolov 18 mars 2019 à 15:42