web-dev-qa-db-fra.com

Évitez les erreurs d'ombre sans ombre avec mapDispatchToProps

J'ai le composant suivant qui déclenche un no-shadow Erreur ESlint sur le FilterButtonprops.

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


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

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

Comment puis-je éviter l'avertissement tout en conservant à la fois 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 tous les composants semble redondant et fastidieux.

48
Kerumen

Il y a quatre options ici:

1. Désactivez la règle.

Pourquoi?

C'est le moyen le plus simple d'éviter l'erreur ESLint.

Pourquoi pas?

La règle sans ombre permet d'éviter un bogue très courant lors de l'utilisation de react-redux. C'est-à-dire, tenter d'appeler l'action brute et non connectée (qui n'est pas automatiquement envoyée).

En d'autres termes, si vous n'utilisiez pas la déstructuration et la récupération de l'action à partir des accessoires, setFilter() ne distribuerait pas l'action (car vous serait invoquer directement l'action importée, par opposition à l'action connectée via des accessoires via props.setFilter(), que react-redux envoie automatiquement pour vous).

En nettoyant ombrage variable , vous et/ou votre IDE sont plus susceptibles de détecter l'erreur).

Comment?

Ajouter une propriété eslintConfig à votre fichier package.json Est ne façon de le faire .

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

2. Réaffectez la variable en la passant dans connect().

Pourquoi?

Vous bénéficiez de la sécurité de la règle sans ombre et, si vous choisissez de respecter une convention de dénomination, c'est très explicite.

Pourquoi pas?

Il présente le passe-partout.

Si vous n'utilisez pas de convention de dénomination, vous devez maintenant trouver des noms alternatifs (qui ont toujours du sens) pour chaque action. Et les chances sont que les mêmes actions soient nommées différemment selon les composants, ce qui rend plus difficile la familiarisation avec les actions elles-mêmes.

Si vous utilisez une convention de dénomination, les noms deviennent longs et répétitifs.

Comment?

Sans convention de dénomination:

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

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

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

Avec convention de dénomination:

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 détruisez pas les actions des accessoires.

Pourquoi?

En utilisant explicitement la méthode hors de l'objet props, vous n'avez pas à vous soucier de l'observation pour commencer.

Pourquoi pas?

Faire précéder toutes vos actions avec props/this.props Est répétitif (et incohérent si vous détruisez tous vos autres accessoires non-action).

Comment?

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

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

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

4. Importez le module entier.

Pourquoi?

C'est concis.

Pourquoi pas?

D'autres développeurs (ou votre futur moi-même) peuvent avoir du mal à comprendre ce qui se passe. Et selon le guide de style que vous suivez, vous violez peut-être la règle de non-importation de caractères génériques .

Comment?

Si vous passez simplement des créateurs d'action à 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 passez dans plusieurs modules, utilisez déstructuration d'objet avec syntaxe de repos :

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 la syntaxe concise d'ES6 dans les commentaires, vous pourriez aussi bien ajouter la fonction flèche avec un retour implicite:

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

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

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

Une cinquième option:

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

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

Pourquoi?

Vous ne voulez pas l'observation variable, mais vous ne pouvez pas le contourner dans certains cas.

Pourquoi pas?

Vous vraiment ne voulez pas l'observation de variables dans votre base de code. ????

8
GollyJer

Option numéro six.

6. Désactivez la règle es-lint pour la ou les lignes de code spécifiques

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. Cela peut être utile si vous passez plus d'arguments et les divisez en plusieurs lignes de code.

Pourquoi?

Il s'agit d'une option facile et appropriée pour 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). Il désactive l'erreur es-lint dans les lignes de code mais n'influence pas la syntaxe mapDispatchToProps et la règle est toujours complètement active en dehors des lignes de code.

Pourquoi pas?

Vous ne voulez pas ou il vous est interdit de gonfler votre code avec ce genre de commentaires. Vous ne voulez pas ou il vous est interdit d'influencer le comportement es-lint.

5
bpalij