4
votes

Pourquoi une liaison deux fois sur onClick est-elle requise dans React?

J'ai un LandingPageComponent qui a un composant enfant DisplayStudent

J'ai une fonction deleteStudent dans LandingPageComponent code >. Je passe cette fonction comme accessoire à DisplayStudent mais je ne comprends pas pourquoi je dois associer function deleteStudent dans LandingPageComponent et DisplayStudent également

J'ai besoin d'obtenir id lorsque le bouton de suppression est cliqué voir ceci sur jsFiddle

jsfiddle

import React, {
  Component
} from 'react';
import DisplayStudent from './DisplayEmployeeComponent'

var data = [{
    name: 'student-1',
    id: 1
  },
  {
    name: 'student-2',
    id: 2
  },
  {
    name: 'student-3',
    id: 3
  }
];

export default class LandingPage extends Component {
  deleteStudent(e) {
    console.log('hi', this, e)
  }

  render() {
    return ( <
      div >
      <
      DisplayStudent studentData = {
        data
      }
      deleteStudent = {
        this.deleteStudent.bind(this)
      } // BINDING FIRST TIME
      /> < /
      div >
    )
  }
}

export default function(props) {
  return (
    props.studentData.map((ele) => {
      return ( <
        div key = {
          ele.id
        }
        style = {
          {
            display: 'flex',
            padding: '9px 5px 7px 4px'
          }
        } >
        <
        div > {
          ele.name
        } < /div>

        <
        button onClick = {
          props.deleteStudent.bind(this, ele.id)
        } // binding second time
        >
        Delete <
        /button> < /
        div >
      )
    })
  )
}


1 commentaires

si vous voulez lier une méthode, vous devez la lier dans le constructeur et non dans la méthode de rendu, si vous ne voulez pas utiliser la liaison, utilisez simplement les fonctions Arrow à la place


5 Réponses :


3
votes

Sans .bind (this) , this à l'intérieur de deleteStudent pointe vers l'objet global ( window ), pas à votre composant.

En savoir plus sur bind et ceci .


1 commentaires

Le premier .bind () n'est-il pas inutile, il a juste besoin de le transmettre à partir de ma connaissance de son fonctionnement, puis de le lier à l'intérieur du composant qui l'utilise



0
votes

Ce n'est pas obligatoire. props.deleteStudent.bind (this, ele.id) est trompeur car this n'est pas utilisable dans un composant fonctionnel (il s'agit d'un code global ou indéfini >) mais cela n'affecte pas deleteStudent car il est déjà lié au contexte approprié.

Si l'intention est de lier un rappel au contexte approprié, il devrait de préférence être lié une fois dans le constructeur de classe:

<button onClick={() => props.deleteStudent(ele.id)}>Delete</button

Et si deleteStudent doit être fourni avec un argument spécifique au lieu de celui qui sera transmis lors de l'événement de clic (objet événement), une méthode plus propre est fonction wrapper:

export default class LandingPage extends Component {
   deleteStudent = this.deleteStudent.bind(this); // syntactic sugar for a constructor

   deleteStudent(e){
       console.log('hi', this, e )
   }

   render(){
       return(
           <div>
               <DisplayStudent studentData = {data}
                            deleteStudent = {this.deleteStudent}
            />
           </div>
       )
  } 
}


5 commentaires

De cette façon, je n'obtiendrai pas ceci dans deleteStudent Je veux dire que this.setState ({}) ne fonctionnera pas dans deleteStudent puisque ce est indéfini


Avez-vous un problème qui peut être reproduit? ceci ne peut pas être indéfini dans deleteStudent car deleteStudent est déjà tenu de corriger ceci dans LandingPage < / code>.


oui ça peut se reproduire il suffit de l'essayer sur jsfiddle que j'ai mentionné dans mon post


Que voulez-vous dire? console.log affiche correctement this et il n'y aura aucun problème avec this.setState . Il le fera également avec les changements suggérés dans la réponse.


ohh je l'ai Vous avez lié en lui le constructeur.



0
votes

La liaison 2 fois n'est pas du tout nécessaire. Bind est utilisé pour passer cette référence à l'intérieur de la fonction. Ainsi, la première liaison dans LandingPage 'DisplayStudent' est suffisante. Il est également conseillé de lier ceci dans le constructeur, car chaque fois que LandingPage le re-rend, il passe une nouvelle référence de fonction à DisplayStudent . La deuxième liaison dans onClick est juste utilisée pour passer le paramètre à la fonction.

P.S. Vous pouvez utiliser la fonction fléchée pour éviter de telles confusions


0 commentaires

1
votes

Vous devez le lier une fois. Si vous le faites deux fois, le second ne s'applique pas. Il est recommandé de l'implémenter sur constructeur juste après super Pour en savoir plus, lisez Fonctions fléchées


0 commentaires

1
votes

Vous pouvez éviter la première liaison même la deuxième liaison dans ES6. Voici un exemple de travail: https://jsfiddle.net/bayucandra/xch1L072/9/




1ère liaison

      <button
        onClick={() => props.deleteStudent(ele.id)}
      > Delete alternative
      </button> 

Ceci est une nouvelle façon de faire bind (this) pour ES6 dans Babel. Juste du sucre syntaxique à l'ancienne. L'ancienne méthode consiste à faire bind (this) dans le constructeur.




2nd bind :

      <button
        onClick={props.deleteStudent.bind(this, ele.id)}
      > Delete
      </button>

Vous avez besoin de ces bind () car vous devez passer ele.id comme argument e de: props.deleteStudent(e)

si vous ne voulez pas le passer de cette façon, vous pouvez utiliser grosse flèche de ES6 comme suit:

  deleteStudent = (e) => {
    console.log('hi', this, e)
  };

De cette façon ci-dessus vous lierez la fonction qui appelle props.deleteStudent (ele.id) à l'intérieur.


3 commentaires

ne peut-il pas être réalisé sans utiliser de grosse flèche ??


Il ne peut pas être réalisé sans liaison ou grosse flèche. Parce que vous devez y passer un argument. faire onClick = {props.deleteStudent} signifiera e valeur de l'argument === non défini . En fait, grosse flèche juste du sucre syntaxique de function () {return props.deleteStudent (ele.id)} . Techniquement, vous liez simplement une fonction à onClick .


Même s'il y a un moyen sans bind () et grosse flèche, cela se terminera par une manière beaucoup plus compliquée :)