82 votes

Éviter l'erreur eslint no-shadow avec mapDispatchToProps

J'ai le composant suivant qui déclenche un no-shadow Erreur ESlint sur la page FilterButton props .

import { setFilter } from '../actions/filter';

function FilterButton({ setFilter }) {
  return (
    <button onClick={setFilter}>Click</button>
  );
}

export default connect(null, { setFilter })(FilterButton);

Comment éviter l'avertissement tout en conservant la syntaxe concise de mapDispatchToProps et la règle ESlint ?

Je sais que je peux ajouter un commentaire pour supprimer l'avertissement, mais le faire pour chaque composant semble redondant et fastidieux.

0 votes

Vous pouvez renommer setFilter ( FilterButton({ setFilter }) a FilterButton({ setFilter }) ). C'est logique (en quelque sorte) parce que les fonctions qui sont dans FilterButton Les accessoires de l'artiste sont en fait l'original setFilter avec le dispatch qui lui est liée.

0 votes

Avant et après le changement de nom, les données sont identiques.

0 votes

Je voulais dire renommer uniquement dans function FilterButton({ setFilter }) { y <button onClick={setFilter}>Click</button> . Pouvez-vous mettre à jour votre question avec le code modifié ?

198voto

jabacchetta Points 2067

Il y a quatre options:

1. Désactiver la règle.

Pourquoi?

C'est la façon la plus simple pour éviter les ESLint erreur.

Pourquoi Pas?

Le pas de l'ombre à la règle contribue à prévenir un très commun de bug lors de l'utilisation d' react-redux. C'est, en tentant d'invoquer la brute, sans lien d'action (qui n'est pas automatiquement expédié).

En d'autres termes, si vous n'étiez pas à l'aide de déstructuration et de l'accaparement de l'action dès les accessoires, setFilter() ne serait pas l'envoi de l'action (parce que vous seriez en invoquant l'importés d'action directement, par opposition à l'invocation de la connectés action par le biais d'accessoires via props.setFilter()qui react-redux automatiquement à l'ordre du jour pour vous).

Par le nettoyage de la variable ombrage, vous et/ou votre IDE sont plus susceptibles de revenir sur l'erreur.

Comment?

L'ajout d'un eslintConfig de la propriété de votre package.json le fichier est une façon de le faire.

"eslintConfig": {
    "rules": {
      "no-shadow": "off",
    }
  }

2. Réaffecter la variable lors du passage en connect().

Pourquoi?

Vous bénéficier de la sécurité de l'ombre à la règle, et, si vous choisissez d'adhérer à une convention de nommage, il est très explicite.

Pourquoi Pas?

Il introduit standard.

Si vous n'avez pas utiliser une convention de nommage, vous avez maintenant de venir avec des noms de remplacement qu'ils ont encore un sens) pour chaque action. Et les chances sont que les mêmes actions seront nommés différemment à travers des composants, ce qui rend plus difficile de se familiariser avec les actions elles-mêmes.

Si vous devez utiliser une convention de nommage des noms longs et répétitifs.

Comment?

Sans convention de nommage:

import { setFilter } from '../actions/filter';

function FilterButton({ filter }) {
  return (
    <button onClick={filter}>Click</button>
  );
}

export default connect(null, { filter: setFilter })(FilterButton);

Avec la convention de nommage:

import { setFilter, clearFilter } from '../actions/filter';

function FilterButton({ setFilterConnect, clearFilterConnect }) {
  return (
    <button onClick={setFilterConnect} onBlur={clearFilterConnect}>Click</button>
  );
}

export default connect(null, {
  setFilterConnect: setFilter,
  clearFilterConnect: clearFilter,
})(FilterButton);

3. Ne pas se déstructurent les actions hors des accessoires.

Pourquoi?

En utilisant explicitement la méthode hors des accessoires de l'objet, vous n'avez pas besoin de s'inquiéter à propos de l'ombrage pour commencer.

Pourquoi Pas?

Ajoutant toutes vos actions avec props/this.props est répétitif (et incohérent si vous êtes à la déstructuration de tous vos autres non-action des accessoires).

Comment?

import { setFilter } from '../actions/filter';

function FilterButton(props) {
  return (
    <button onClick={props.setFilter}>Click</button>
  );
}

export default connect(null, { setFilter })(FilterButton);

4. Importer l'ensemble du module.

Pourquoi?

C'est concis.

Pourquoi Pas?

D'autres développeurs (ou votre soi futur) peuvent avoir de la difficulté à comprendre ce qu'il se passe. Et selon le guide de style, vous êtes, vous pourriez être de casser la non-générique-les importations de la règle.

Comment?

Si vous êtes simplement de passage dans l'action des créateurs à partir d'un module:

import * as actions from '../actions/filter';

function FilterButton({ setFilter }) {
  return (
    <button onClick={setFilter}>Click</button>
  );
}

export default connect(null, actions)(FilterButton);

Si vous êtes de passage dans plusieurs modules, l'utilisation de l'objet de déstructuration avec le reste de la syntaxe:

import * as filterActions from '../actions/filter';
import * as otherActions from '../actions/other';

// all exported actions from the two imported files are now available as props
function FilterButton({ setFilter, clearFilter, setOther, clearOther }) {
  return (
    <button onClick={setFilter}>Click</button>
  );
}

export default connect(null, { ...filterActions, ...otherActions })(FilterButton);

Et puisque vous avez mentionné une préférence pour l'ES6 s concise de la syntaxe dans les commentaires, pourrait tout aussi bien jeter dans la flèche de la fonction avec un rendement implicite:

import * as actions from '../actions/filter';

const FilterButton = ({ setFilter }) => <button onClick={setFilter}>Click</button>;

export default connect(null, actions)(FilterButton);

1 votes

Nous vous remercions ! Cela devrait être la réponse acceptée, c'est certain.

5 votes

Réponse très bien rédigée. Bien qu'il faille arrêter la lecture après Disable the rule :)

0 votes

C'est ce type de réponse qui fait du SO la ressource exceptionnelle qu'il est.

14voto

GollyJer Points 1108

Une cinquième option :

5. Autoriser une exception spécifique via eslintrc règles.

module.exports = {
  rules: {
    'no-shadow': [
      'error',
      {
        allow: ['setFilter'],
      },
    ],
  }
}

Pourquoi ?

Vous ne voulez pas d'ombres variables, mais vous ne pouvez pas vous en passer dans certains cas.

Pourquoi pas ?

Vous vraiment vous ne voulez pas d'ombre de variable dans votre base de code.

0 votes

J'aime cette option, mais elle ne fonctionne pas pour moi.

8voto

bpalij Points 151

Option numéro six.

6. Désactiver la règle es-lint pour la (les) ligne(s) de code spécifique(s)

import { setFilter } from '../actions/filter';

// eslint-disable-next-line no-shadow
function FilterButton({ setFilter }) {
  return (
    <button onClick={setFilter}>Click</button>
  );
}

export default connect(null, { setFilter })(FilterButton);

ou

import { setFilter } from '../actions/filter';

/* eslint-disable no-shadow */
function FilterButton({ setFilter }) {
/* es-lint-enable */
  return (
    <button onClick={setFilter}>Click</button>
  );
}

export default connect(null, { setFilter })(FilterButton);

La deuxième façon de désactiver temporairement la règle es-lint peut être utilisée pour plusieurs lignes de code, contrairement à la première. Elle peut être utile si vous passez plus d'arguments et que vous les divisez en plusieurs lignes de code.

Pourquoi ?

Il s'agit d'une option simple et adaptée à certains cas d'utilisation (par exemple, votre équipe/organisation utilise des paramètres es-lint spécifiques et il est déconseillé/interdit de modifier ces paramètres). Elle désactive l'erreur es-lint dans la (les) ligne(s) de code mais n'a pas d'influence sur les éléments suivants mapDispatchToProps et la règle reste complètement active en dehors de la ou des lignes de code.

Pourquoi pas ?

Vous ne voulez pas ou vous n'avez pas le droit de gonfler votre code avec ce genre de commentaires. Vous ne voulez pas ou vous n'avez pas le droit d'influencer le comportement d'es-lint.

5voto

gqstav Points 1500

J'ai modifié le point 4 et j'ai obtenu ce que j'aimerais appeler l'option 8.

8. Importer des méthodes sous un nom différent

Pourquoi ?

Elle présente les mêmes avantages que l'importation du module entier, mais sans entrer en conflit avec d'autres règles, par exemple Ne pas utiliser de caractères génériques pour les importations (airbnb) .

Pourquoi pas ?

Il ajoute une déclaration de variable inutile qui peut prêter à confusion.

Comment ?

Dans le cas d'une méthode unique

import { setFilter as setFilterConnect } from '../actions/filter';

function FilterButton({ setFilter }) {
  return <button onClick={setFilter}>Click</button>;
}

export default connect(
  null,
  { setFilter: setFilterConnect }
)(FilterButton);

4voto

Mark Dreyer Points 94

Avec la nouvelle API de crochets ajoutée dans la v7.1.0, vous pouvez vous débarrasser de la variable et de la mapDispatchToProps tout à fait :

import { useDispatch } from 'react-redux'
import { setFilter } from '../actions/filter';

function FilterButton() {
  const dispatch = useDispatch()
  return (
    <button onClick={dispatch(setFilter())}>Click</button>
  );
}

export default FilterButton;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X