web-dev-qa-db-fra.com

Utilisation correcte des fonctions de flèche dans React

J'utilise ReactJS avec Babel et Webpack et j'utilise ES6 ainsi que le champs de classe proposés pour les fonctions de flèche. Je comprends que les fonctions de flèche rendent les choses plus efficaces en ne pas recréer les fonctions que chaque rend de la même manière que la liaison dans le constructeur. Cependant, je ne suis pas sûr à 100% si je les utilise correctement. Ce qui suit est une section simplifiée de mon code dans trois fichiers différents.

Mon code:

Main.js

prevItem = () => {
    console.log("Div is clicked")
}

render(){
    return (
         <SecondClass prevItem={this.prevItem} />
    )
}

SecondClass.js

<ThirdClass type="prev" onClick={()=>this.props.prevItem()} />

ThirdClass.js

<div onClick={()=>{this.props.onClick()}}>Previous</div>

Question:

Mon code ci-dessus utilisant la flèche fonctionne-t-il correctement? J'ai remarqué que pour SecondClass.js, j'aurais aussi pu utiliser:

<ThirdClass type="prev" onClick={this.props.prevItem} />

Existe-t-il une différence entre l'une ou l'autre méthode puisque j'ai utilisé une fonction de flèche ES6 dans ma définition de fonction d'origine? Ou devrais-je utiliser la syntaxe de la flèche tout au long de ma dernière div?

31
kojow7

Je comprends que les fonctions de flèche rendent les choses plus efficaces en ne recréant pas les fonctions que chacune rend de la même manière que la liaison dans le constructeur.

Ce n'est pas vrai. Cela dépend où vous utilisez exactement la fonction Flèche. Si _Arrow function_ sont utilisés dans la méthode de rendu, ils créent une nouvelle instance. everytime render est appelé de la même manière que bind fonctionnerait. Considérez cet exemple

_<div onClick={()=>{this.onClick()}}>Previous</div>
_

Ici, chaque fois que le rendu est appelé, une fonction anonyme est créée et cette fonction appelée, appelle _this.onClick_.

Cependant, considérons le cas ci-dessous

_onClick = () => {
    console.log("Div is clicked")
}
_

Dans le cas ci-dessus, la fonction de flèche ne recrée pas la fonction à chaque fois, mais lie le contexte au composant React en tant que _An arrow function does not have its own this; the this value of the enclosing execution context is used._ une fois lorsque la classe est instanciée. Ceci est similaire à la façon dont _binding works is constructor_. Ceci fait partie de _proposed class fields for arrow functions_ et ce n'est pas une fonctionnalité ES6,

Pour comprendre ce que vous souhaitez demander, vous devez savoir qu'une fonction tire son contexte de l'endroit où elle est appelée. Cochez this question pour plus de compréhension.

Dans votre cas, vous avez utilisé _Arrow function_ pour définir prevItem et ainsi obtenir le contexte du composant React englobant.

_prevItem = () => {
    console.log("Div is clicked")
}

render(){
    return (
         <SecondClass prevItem={this.prevItem} />
    )
}
_

Maintenant dans son enfant, même si vous appelez prevItem avec n’importe quel contexte personnalisé, _using bind or arrow function_, prevItem lorsqu’il est exécuté dans le parent, c.-à-d. _Main.js_ obtiendra le contexte de son React composant. Et puisque vous souhaitez simplement exécuter la fonction prevItem et que vous ne souhaitez pas lui transmettre de données,

_<ThirdClass type="prev" onClick={()=>this.props.prevItem()} />
_

et

_<div onClick={()=>{this.props.onClick()}}>Previous</div>
_

est simplement inutile et ne fera qu'ajouter à l'implication dans les performances puisque de nouvelles fonctions sont créées dans SecondClass et ThirdClass à chaque fois. Vous n'avez simplement pas besoin de définir ces fonctions en tant que fonction de flèche et vous pouvez simplement écrire

_<ThirdClass type="prev" onClick={this.props.prevItem} />
_

et

_<div onClick={this.props.onClick}>Previous</div>
_

depuis sa déjà liée dans le parent.

Maintenant, même si vous devez transmettre des données supplémentaires à ces fonctions à partir de ThirdClass et SecondClass, vous ne devriez pas utiliser directement _Arrow function_ ou _bind in render_. Regardez cette réponse sur How to Avoid binding in Render method

29
Shubham Khatri

Donc, votre première approche

<ThirdClass type="prev" onClick={()=>this.props.prevItem()} />

En cela, vous pouvez transmettre tous les arguments disponibles dans ThirdClass à la fonction prevItem. C’est le bon moyen d’appeler des fonctions parent avec des arguments.

<ThirdClass type="prev" onClick={()=>this.props.prevItem(firstArgument, secondArgument)} />

Votre deuxième approche est

<ThirdClass type="prev" onClick={this.props.prevItem} />

Cette approche vous interdit de passer des arguments spécifiques à ThirdClass.

Les deux démarches sont correctes, ça dépend de votre cas d'utilisation. Les deux approches utilisant la fonction es6 flèche sont exactes dans les scénarios respectifs mentionnés ci-dessus

6
simbathesailor

L'utilisation de JavaScript déclaration de fonction récurrente, peut être différente des autres réponses, faites attention aux codes suivants:

clickHandler = someData => e => this.setState({
  stateKey: someData
});

Maintenant, dans JSX, vous pouvez écrire:

<div onClick={this.clickHandler('someData')} />

La clickHandler avec someData renvoie une fonction avec l'argument e, mais elle n'est pas utilisée dans la fonction clickHandler. alors ça marche bien.

Pour écrire plus complètement, écrivez comme ci-dessous:

clickHandler = someData => () => this.setState({
  stateKey: someData
});

Il n'est pas nécessaire de e, alors pourquoi devrais-je l'écrire?.

4
AmerllicA

L'utilisation de flèches dans votre définition de fonction d'origine vous permet de ne pas lier la fonction dans votre constructeur.

Si vous n'avez pas utilisé de flèche ...

prevItem(){
  console.log("Div is clicked")
}

Ensuite, vous devrez créer un constructeur pour le lier là-bas ...

class MyComponent extends Component {
  constructor(props) {
    super(props)
    this.prevItem = this.prevItem.bind(this)
  }

  prevItem() { ... }
}

L'utilisation de la flèche est plus facile lorsque vous commencez, car elle fonctionne et vous n'avez pas à comprendre ce qu'est un constructeur et à vous plonger dans les complexités de this en javascript.

Cependant, en termes de performances, il est préférable de lier le constructeur. La méthode constructeur dans bind in crée une instance unique de la fonction et la réutilise, même si la méthode de rendu est appelée plusieurs fois.

3
Josh Pittman