
Inspiré par les articles lus sur le support, j'ai décidé d'écrire mon article et de vous dire comment éviter les erreurs les plus courantes dans votre application React et pourquoi vous devez le faire.
Tout le code est écrit dans le style ES6, donc pour le répéter, vous devez utiliser Babel dans votre projet (et il y en a d'autres qui ne l'utilisent pas?).
J'ai essayé d'expliquer chaque erreur avec autant de détails que possible, par conséquent, mon article est plus axé sur les jeunes développeurs qui sont toujours à la recherche de nouvelles connaissances. Bien que, il me semble, un développeur expérimenté peut trouver quelques choses intéressantes pour lui-même dans cet article.
Si vous êtes intéressé, alors bienvenue au chat.
Entre crochets avant chaque paragraphe, j'ai laissé un lien vers la règle eslint. Vous pourrez ensuite les retrouver dans git et les ajouter à votre projet.
(réagir / interdire les accessoires des composants)
La première erreur courante consiste à transmettre «style» et «className» comme accessoires à votre composant. Évitez cela car vous ajoutez beaucoup de complexité à vos composants.
Au lieu de cela, vous pouvez utiliser la bibliothèque 'classnames' et ajouter des variations intéressantes à votre composant (si vous utilisez des classes css):
const { hasError, hasBorder } = this.props; const componentClasses = classnames({ 'your-component-main-class': true, 'your-component-main-class_with-error': hasError, 'your-component-main-class_with-border': hasBorder, });
(réagir / interdire-prop-types)
L'erreur suivante n'est pas propTypes informative. N'utilisez pas PropTypes.any, PropTypes.array et PropTypes.object. Décrivez vos accessoires aussi détaillés que possible. Cela vous permettra de laisser une bonne documentation pour l'avenir, et vous (ou un autre développeur) vous en remercierez plusieurs fois.
class MyComponent extends React.Component { static propTypes = { user: PropTypes.shape({ id: PropTypes.number, name: PropTypes.string, }), policies: PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.number, type: PropTypes.string, value: PropTypes.string, }), } }
(réagir / interdire-types-prop-étrangers)
Continuons avec propTypes. N'utilisez pas les propTypes d'un autre composant:
import SomeComponent from './SomeComponent'; SomeComponent.propTypes;
Créez un fichier dans lequel vous conserverez vos propTypes globaux dans l'ordre:
import { userShape, policiesArray } from '../common/global_prop_types';
Cela vous aidera babel-plugin-transformer-react- remove-prop-types loin de Code propTypes Prodakshen et faites votre demande un peu plus facile.
(état réactif / sans accès à l'état initial)
L'erreur suivante est très intéressante:
class MyComponent extends React.Component { state = { counter: 1, }; incrementCounter = () => this.setState({ counter: this.state.counter + 1 }); massIncrement = () => { // this code will lead to not what you expect this.incrementCounter(); this.incrementCounter(); } }
Parce que setState est une fonction d'état asynchrone de l'état dans les deux cas sera la même.
this.state.counter sera 1 et nous obtiendrons:
incrementCounter = () => this.setState({ counter: 1 + 1 }); incrementCounter = () => this.setState({ counter: 1 + 1 });
Pour éviter cela, vous pouvez utiliser le rappel setState qui reçoit l'état d'état comme argument:
incrementCounter = () => this.setState((prevState) => ({ counter: prevState.counter + 1 }));
(clé d'index react / no-array-key)
Cette erreur est également très courante, par conséquent, lisez attentivement et évitez-la à l'avenir:
users.map((user, index) => ( <UserComponent {...user} key={index} /> ));
React utilise la clé prop comme lien vers l'élément DOM, ce qui l'aide à trouver et à rendre rapidement le composant nécessaire (tout, bien sûr, est plus compliqué, mais je l'ai simplifié à dessein).
Que se passe-t-il si vous ajoutez un nouvel utilisateur au milieu du tableau? React sera obligé de restituer tous les UserComponents après l'ajout d'un nouveau, car l'index sera modifié pour un grand nombre de composants. Utilisez plutôt des clés uniques. Un moyen très simple de sortir est l'ID que vous obtenez de votre base de données:
users.map((user) => ( <UserComponent {...user} key={user.id} /> ));
(état réactif / no-did-mount-set), (état réactif / no-did-update-set)
Cette erreur est également très courante dans ma pratique. Si vous essayez de mettre à jour l'état dans la méthode componentDidUpdate, vous obtenez une boucle de restitution infinie. React démarre une vérification du nouveau rendu lorsque le composant change d'état ou d'accessoires. Si vous changez d'état après que le composant est monté dans le DOM ou a déjà été mis à jour, vous exécuterez la vérification encore et encore et encore ...
Lors de la mise à jour de l'état dans componentDidMount, vous pouvez appeler à nouveau le rendu du composant, car la fonction est appelée une fois après le montage du composant dans le DOM.
Si vous devez mettre à jour les données après avoir monté le composant, je suggère d'utiliser des variables de classe:
class MyComponent extends React.Component { componentDidMount() { this.veryImportantDataThatCanBeStoredOnlyAfterMount = 'I'll be back!'; } veryImportantDataThatCanBeStoredOnlyAfterMount = void 0; render() { return <div /> } }
(état réactif / sans mutation directe)
La mutation d'état est une très grosse erreur. Une mutation d'état incontrôlée entraînera des bogues indétectables et, par conséquent, de gros problèmes. Mon opinion personnelle est l'utilisation de immutable-js , comme une bibliothèque qui ajoute des structures immuables. Et vous pouvez les utiliser avec Redux / MobX / Toute bibliothèque de gestion d'état. Vous pouvez également utiliser deepClone de lodash pour cloner l'état, puis muter le clone, ou utiliser la nouvelle fonctionnalité JS - la déstructuration:
updateStateWrong = () => this.state.imRambo = true; updateStateRight = () => { const clonedState = cloneDeep(this.state); clonedState.imAGoodMan = true; this.setState(clonedState); } updateWithImmutabelJS = () => { const newState = this.state.data.set('iUseImmutableStructure', true); this.setState(data: newState); } updateWithDestructuring = () => this.setState({ ...this.state, iUseDestructuring: true });
(fonction réagir / préférer sans état)
Cette règle décrit plus d'amélioration de votre code et de votre application qu'une erreur, mais je vous recommande tout de même de suivre cette règle. Si votre composant n'utilise pas d'état, faites-en un composant sans état (je préfère le terme «composant pur»):
class MyComponentWithoutState extends React.Component { render() { return <div>I like to write a lot of unneeded code</div> } } const MyPureComponent = (props) => <div>Less code === less support</div>
(types de réaction / prop)
Veuillez toujours ajouter la vérification du type d'accessoires (propTypes) si votre composant reçoit des accessoires. Considérez-le comme documentant votre code. Plus d'une fois, vous vous direz «merci» pour cela (et peut-être à moi :)). PropTypes vous aidera à comprendre et à comprendre ce que votre composant peut rendre, ainsi que ce dont il a besoin pour le rendu.
MyPureComponent.propTypes = { id: PropTypes.number.isRequired, // And I know that without id component will not render at all, and this is good. }
(réagir / jsx-no-bind)
Une erreur très courante et très importante que j'ai vue plusieurs fois dans le code. N'utilisez pas la fonction de liaison et de flèche dans Jsx. Jamais. Plus.
L'endroit le plus chaud en enfer attend celui qui écrit .bind (this) dans JSX dans le gestionnaire d'événements.
Chaque fois qu'un composant est rendu, votre fonction sera recréée, ce qui peut considérablement ralentir votre application (cela est dû au fait que le garbage collector sera forcé de s'exécuter beaucoup plus souvent). Au lieu de .bind (ceci), vous pouvez utiliser les fonctions Flèche d'une certaine manière:
class RightWayToCallFunctionsInRender extends React.Component { handleDivClick = (event) => event; render() { return <div onClick={this.handleDivClick} /> } } const handleDivClick = (event) => event; const AndInPureComponent = () => { return <div onClick={handleDivClick} /> }
(react / jsx-no-target-blank)
Bug de sécurité. Il me semble très étrange que les gens commettent encore cette erreur. Beaucoup de gens ont écrit beaucoup d'articles sur ce sujet en 2017.
Si vous créez un lien avec l'attribut target = '_ blank', assurez-vous de lui ajouter rel = 'noreferrer noopener'. Très simple:
<a href="https://example.com" target="_blank" rel="noreferrer noopener" />
Je vous remercie
C'est tout ce que je voudrais vous dire dans le cadre de cet article. Je serai très reconnaissant si vous, mes lecteurs, me laissez vos commentaires ou commentaires et partagez votre opinion en ce qui concerne les problèmes que j'ai décrits dans cet article. Vous pouvez également me parler de mes erreurs et de vos erreurs dans le code et de tout ce que vous jugez nécessaire de dire. Merci encore!