1
votes

Accéder aux variables du constructeur dans la méthode de rendu - Reactjs

J'ai un formulaire d'inscription simple comme indiqué dans le code ci-dessous et j'ai pour objectif d'afficher mon message de validation lors de l'envoi. Le code est principalement en react et pure js.

console.log('validationMsg', this.validationMsg);

Ma question est de savoir comment puis-je accéder à this.validationMsg déclaré dans le constructeur depuis le render Méthode.

En gros, ce que je dis, c'est que mon {this.validationMsg.username} ou {this.validationMsg.email} ne fonctionne pas, ce qui signifie qu'il n'affiche rien et aucune erreur n'est générée.

Cependant, lorsque je clique sur Soumettre, je peux voir le résultat souhaité dans la fonction handleSubmit à

import React from 'react';

class Register extends React.Component {

    constructor() {
        super();
        this.handleSubmit  = this.handleSubmit.bind(this);
        this.validationMsg = [];
    }

    handleSubmit(event) {
        event.preventDefault();

        let target   = event.target;

        for (let i = 0; i < target.length; i++) {

            let item = target.elements[i];
            let name = item.getAttribute("name")
            let msg  = name + ' is required.'

            if (item.value === '') {
                this.validationMsg.push({
                    [name]: msg
                });
            }
        }
        console.log('validationMsg', this.validationMsg);
    }

    render () {
        return (
            <form onSubmit={this.handleSubmit}>
                <input type="text" name="username" />
                {this.validationMsg.username}
                <input type="text" name="email" />
                {this.validationMsg.email}
                <input type="submit" name="submit" value="SIGN UP" />
            </form>
        );
    }
}

export default Register;

Comment puis-je afficher les valeurs de this.validationMsg dans la méthode render ()?


2 commentaires

this.validationMsg est une liste.


Eh bien, notez que tout changement dans validationMsg ne provoque pas de nouveau rendu.


5 Réponses :


0
votes

Essayez de changer votre validationMsg en objet

import React from 'react';

class Register extends React.Component {
    constructor() {
        super();
        this.handleSubmit  = this.handleSubmit.bind(this);
        this.validationMsg = {};
    }

    handleSubmit(event) {
        event.preventDefault();

        let target = event.target;

        for (let i = 0; i < target.length; i++) {

            let item = target.elements[i];
            let name = item.getAttribute("name")
            let msg  = name + ' is required.'

            if (item.value === '') {
                this.validationMsg[name] = msg;
            }
        }
        console.log('validationMsg', this.validationMsg);
    }

    render () {
        return (
            <form onSubmit={this.handleSubmit}>
                <input type="text" name="username" />
                {this.validationMsg.username}
                <input type="text" name="email" />
                {this.validationMsg.email}
                <input type="submit" name="submit" value="SIGN UP" />
            </form>
        );
    }
}

export default Register;


0 commentaires

0
votes

Comme this.validationMsg est une liste, vous devriez donc être remplacé par this.validationMsg = {} .

Ajouter une valeur de clé dans un objet: p>

this.state = {
   validationMsg: {}
}

if (item.value === '') {
   const validationMsgTmp = ...this.state.validationMsg; 
   // Create a deep clone this.state
   this.setState({
      ...this.state,
      validationMsg: validationMsgTmp[name] = msg 
      // Add key: value into object state
   })
}

Mais , dans votre cas, vous devriez utiliser this.state pour gérer l'erreur comme ceci:

XXX


0 commentaires

0
votes

Utilisez state pour cela. Vous pouvez trouver une documentation détaillée ici

In reactjs l'état d'un la classe détient tout. Si vous mettez à jour l ' état . La fonction de rendu est rappelée avec la valeur mise à jour.

Pour ce faire, vous devez utiliser setState . J'ai apporté quelques modifications à votre code pour expliquer cela.

return (
    <form onSubmit={this.handleSubmit}>
        <input type="text" name="username" />
        {this.state.validationMsg.username}
        <input type="text" name="email" />
        {this.state.validationMsg.email}
        <input type="submit" name="submit" value="SIGN UP" />
    </form>
);

Votre fonction de rendu devrait être comme ceci:

    constructor() {
    super();
    this.handleSubmit  = this.handleSubmit.bind(this);
    this.state = {
        validationMsg = []
    }
}
handleSubmit(event) {
    event.preventDefault();

    //Changes here
    let validation = [];

    let target   = event.target;

    for (let i = 0; i < target.length; i++) {

        let item = target.elements[i];
        let name = item.getAttribute("name")
        let msg  = name + ' is required.'

        if (item.value === '') {
            validation.push({
                [name]: msg
            });
        }
    }
    console.log('validationMsg', this.validationMsg);
    this.setState({validationMsg: validation})
}

p >


0 commentaires

0
votes

Vous déclarez this.validationMsg en tant que tableau, puis essayez d'y accéder en tant qu'objet individuel. Vous pouvez plutôt envisager d'utiliser map :

  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.state = {
      validationMsg: []
    }
  }

 handleSubmit(event) {
  event.preventDefault();

  let target = event.target;
  const message = [];
  for (let i = 0; i < target.length; i++) {

    let item = target.elements[i];
    let name = item.getAttribute("name")
    let msg = name + ' is required.'

    if (item.value === '') {
      message.push({
        [name]: msg
      });
    }

  }

  this.setState({
    validationMsg: message
  });
}


// then in render
const {validationMsg} = this.state; 

return (
  <form onSubmit={this.handleSubmit}>
    <input type="text" name="username" />
    {validationMsg.map(message => message.username)}
    <input type="text" name="email" />
    {validationMsg.map(message => message.email)}
    <input type="submit" name="submit" value="SIGN UP" />
  </form>
);

En général, il est préférable de sauvegarder ce type de données dans l'état, car vous l'utilisez pour le rendu: p >

return (
  <form onSubmit={this.handleSubmit}>
    <input type="text" name="username" />
    {this.validationMsg.map(message => message.username)}
    <input type="text" name="email" />
    {this.validationMsg.map(message => message.email)}
    <input type="submit" name="submit" value="SIGN UP" />
  </form>
);


0 commentaires

0
votes

Vos messages d'erreur sont en fait stockés dans une variable normale de votre classe. Ainsi, le composant ne s'affichera pas pour afficher le message d'erreur. Vous devez le stocker dans l ' état du composant. Vous pouvez trouver plus de détails sur la manière dont les composants de réaction gèrent les modifications de données ici . Voici le code de mise à jour qui utilise l'état. Et le codepen .

class Register extends React.Component {
    constructor() {
        super();
        this.handleSubmit  = this.handleSubmit.bind(this);
        this.state = {
          validationMsg: {}
        };
    }

    handleSubmit(event) {
        event.preventDefault();

        let target = event.target;
        const validationMsg = {};

        for (let i = 0; i < target.length; i++) {

            let item = target.elements[i];
            let name = item.getAttribute("name")
            let msg  = name + ' is required.'

            if (item.value === '') {
              validationMsg[name] = msg;
            }
        }
        this.setState({ validationMsg });
    }

    render () {
        return (
            <form onSubmit={this.handleSubmit}>
                <input type="text" name="username" />
                {this.state.validationMsg.username}
                <input type="text" name="email" />
                {this.state.validationMsg.email}
                <input type="submit" name="submit" value="SIGN UP" />
            </form>
        );
    }
}

p >


0 commentaires