Il y a quatre options ici:
1. Désactiver la règle.
Pourquoi?
C'est la manière la plus simple d'éviter l'erreur ESLint.
Pourquoi pas?
La règle no-shadow aide à prévenir un bug très courant lors de l'utilisation de react-redux
. C'est-à-dire, essayer d'invoquer l'action brute et non connectée (qui n'est pas automatiquement envoyée).
En d'autres termes, si vous n'utilisiez pas la destructuration et obteniez l'action des props, setFilter()
n'enverrait pas l'action (car vous invoqueriez directement l'action importée, au lieu d'invoquer l'action connectée via les props avec props.setFilter()
, que react-redux
envoie automatiquement pour vous).
En nettoyant le masquage des variables, vous et/ou votre IDE êtes plus susceptibles de repérer l'erreur.
Comment?
Ajouter une propriété eslintConfig
à votre fichier package.json
est une manière de le faire.
"eslintConfig": {
"rules": {
"no-shadow": "off",
}
}
2. Réattribuer la variable lors de son passage dans connect()
.
Pourquoi?
Vous bénéficiez de la sécurité de la règle no-shadow, et, si vous choisissez de respecter une convention de nommage, cela devient très explicite.
Pourquoi pas?
Cela introduit du boilerplate.
Si vous n'utilisez pas de convention de nommage, vous devez maintenant trouver des noms alternatifs (qui ont toujours du sens) pour chaque action. Et il y a de fortes chances que les mêmes actions aient des noms différents d'un composant à l'autre, ce qui rend plus difficile de se familiariser avec les actions elles-mêmes.
Si vous utilisez une convention de nommage, les noms deviennent longs et répétitifs.
Comment?
Sans convention de nommage:
import { setFilter } from '../actions/filter';
function FilterButton({ filter }) {
return (
Cliquez
);
}
export default connect(null, { filter: setFilter })(FilterButton);
Avec convention de nommage:
import { setFilter, clearFilter } from '../actions/filter';
function FilterButton({ setFilterConnect, clearFilterConnect }) {
return (
Cliquez
);
}
export default connect(null, {
setFilterConnect: setFilter,
clearFilterConnect: clearFilter,
})(FilterButton);
3. Ne pas déstructurer les actions des props.
Pourquoi?
En utilisant explicitement la méthode du objet props, vous n'avez pas besoin de vous soucier du masquage au départ.
Pourquoi pas?
Précéder toutes vos actions de props
/this.props
est répétitif (et incohérent si vous déstructurez toutes vos autres props non-actions).
Comment?
import { setFilter } from '../actions/filter';
function FilterButton(props) {
return (
Cliquez
);
}
export default connect(null, { setFilter })(FilterButton);
4. Importer l'ensemble du module.
Pourquoi?
C'est concis.
Pourquoi pas?
D'autres développeurs (ou votre futur moi) pourraient avoir du mal à comprendre ce qui se passe. Et en fonction du guide de style que vous suivez, vous pourriez enfreindre la règle no-wildcard-imports.
Comment?
Si vous envoyez simplement des créateurs d'actions d'un module:
import * as actions from '../actions/filter';
function FilterButton({ setFilter }) {
return (
Cliquez
);
}
export default connect(null, actions)(FilterButton);
Si vous envoyez plusieurs modules, utilisez la déstructuration d'objet avec la syntaxe rest:
import * as filterActions from '../actions/filter';
import * as otherActions from '../actions/other';
// toutes les actions exportées des deux fichiers importés sont maintenant disponibles en tant que props
function FilterButton({ setFilter, clearFilter, setOther, clearOther }) {
return (
Cliquez
);
}
export default connect(null, { ...filterActions, ...otherActions })(FilterButton);
Et comme vous avez mentionné une préférence pour la syntaxe concise d'ES6 dans les commentaires, autant ajouter la fonction fléchée avec un retour implicite :
import * as actions from '../actions/filter';
const FilterButton = ({ setFilter }) => Cliquez;
export default connect(null, actions)(FilterButton);
0 votes
Vous pouvez renommer
setFilter
(FilterButton({ setFilter })
enFilterButton({ setFilter })
). Cela a du sens (en quelque sorte) car la fonction qui se trouve dans les proprétés deFilterButton
est en réalité l'originalesetFilter
avec la fonctiondispatch
qui lui est liée.0 votes
Avant et après le renommage sont les mêmes.
0 votes
Je voulais simplement renommer dans
function FilterButton({ setFilter }) {
etCliquez
. Pouvez-vous mettre à jour votre question avec le code modifié?0 votes
Je ne peux pas le renommer en
function FilterButton({ setFilter })
car il doit correspondre au nom de la propriété qui est en faitsetFilter
.3 votes
Ne pouvez-vous pas simplement réaffecter lorsque vous le passez à la fonction sur la ligne d'exportation ? Ainsi,
export default connect(null, {filter: setFilter})(FilterButton);
et ensuite juste au-dessus de celafunction FilterButton ({filter}) {
(ou tout autre nom de variable que vous préférez). De cette façon, vous ne masquez pas la variable dans la portée supérieure, et c'est clair en regardant le code.0 votes
Dans ce cas, je perdrais la syntaxe concise d'ES6.
0 votes
Ce serait génial s'il existait un plugin eslint forké qui désactive no-shadow juste pour ce cas d'utilisation particulier. J'apprécie no-shadow en principe mais ce code est bien meilleur que les alternatives.
0 votes
Un problème similaire (avec des solutions similaires) existe pour
mapStateToProps
lors de l'utilisation decreateStructuredSelector
de reselect avec des noms identiques pour les propriétés et les sélecteurs. Exemple:connect(createStructuredSelector({ filter }), null)(Component)