Cet article a été impliqué dans「Le programme Nugget Star」,.Gagner un grand sac cadeau pour la création,Remise en question des incitatifs à la création.
Je suis désolé.,J'ai abandonnéVue,VirementsReactCamp.Pas à cause d'autres,Juste parce qu'il est utilisé de mon côtéReactLe rapport salaire / utilisation deVueLes salaires sont élevés.
Avant juin,J'ai endurci des centaines deReactQuestions d'entrevue,Utilisation par la famille d'accueilReactEntreprises,Augmentation de salaire120%;
L'entrée en fonction est immédiatement entrée dans la phase de développement,A partir de zéro,Avec le temps,DécouverteReactL'entrée n'est pas aussi difficile que le Web.Est - ce que je suis né pour manger ce bol de riz…………
Ça fait six mois aujourd'hui,Je suis ici pour partager les fruits de cette période avec mes amis de la fosse,S'il vous plaît, apprenez plus,Progresser ensemble.
En plus, j'utiliseReact16.8Pour commencer,Par conséquent, la plupart desComposants fonctionnelsEtReact HooksPour développer.
Rappel de poids lourd,Il y a un tirage au sort à la fin de l'article.
Un composant fonctionnel peut être interprété comme un composant qui renvoieReactFonction de l'élément,Il reçoit un paramètre représentant les propriétés du composantprops
.
InReact16.8Avant,Ce qui veut dire qu'il n'y a pasReact HooksAvant,Les composants fonctionnels ne sont utilisés que commeUIComponents, Sa sortie est entièrement paramétrée props
Contrôle, Pas d'état propre pas de code logique d'entreprise ,Est une fonction pure. Composant fonctionnel sans instance ,Pas de cycle de vie, Appelé composant apatride .
InReact HooksAprès l'apparition,Ça marcheHook Attribution de l'état et du cycle de vie des composants fonctionnels , Ainsi, les composants fonctionnels peuvent également être utilisés comme composants commerciaux .
En cours de développement, Les composants de classe et de fonction sont utilisés , Après six mois de développement , Les composants fonctionnels sont meilleurs que les composants de classe , Les points les plus profonds sont les suivants: :
Il y a une différence très importante entre les composants fonctionnels et les composants de classe : Les composants fonctionnels saisissent les valeurs utilisées pour le rendu .
J'en ai rencontré un. BUG Je savais qu'il y avait une différence. , C'est réglé. BUG Le processus de compréhension de cette différence .
Celle - là.BUG C'est comme ça. ,Une boîte d'entrée, Fin de la saisie , Cliquez sur le bouton pour rechercher , Demander une interface lors de la recherche , Obtenir un type , Demander une interface de recherche avec le type et la valeur de la boîte d'entrée . Décrivez brièvement le Code .
import React, { Component } from "react";
import * as API from 'api/list';
class SearchComponent extends Component {
constructor() {
super();
this.state = {
inpValue: ""
};
}
getType () {
const param = {
val:this.state.inpValue
}
return API.getType(param);
}
getList(type){
const param = {
val:this.state.inpValue,
type,
}
return API.getList(param);
}
async handleSearch() {
const res = await this.getType();
const type = res?.data?.type;
const res1 = await this.getList(type);
console.log(res1);
}
render() {
return (
<div>
<input
type="text"
value={this.state.inpValue}
onChange={(e) => {
this.setState({ inpValue: e.target.value });
}}
/>
<button
onClick={() => {
this.handleSearch();
}}
>
Recherche
</button>
</div>
);
}
}
export default SearchComponent;
Copier le Code
Il n'y a rien de mal à la logique de code ci - dessus. ,MaisQA J'en ai choisi un. BUG, Après avoir entré le contenu à rechercher dans la zone d'entrée , Cliquez sur le bouton recherche pour commencer la recherche , Puis vous tapez rapidement dans la zone d'entrée , Interface de recherche de résultats getList
Erreur signalée. Vérifiez la raison. , Discovery is get type interface getType
Et interface de recherche getList
Paramètres acceptés val
Incohérence.
Pendant le dépannage , Je me demande. , Dans les deux demandes val
Tout est luthis.state.inpValue
Valeur de. À ce moment - là, mes collègues m'ont demandé de passer à un composant fonctionnel pour résoudre ce problème. BUG.
import React, { useState } from "react";
import * as API from 'api/list';
export const SearchComponent = () =>{
const [inpValue,setInpValue] = useState('');
const getType = () =>{
const param = {
val:inpValue
}
return API.getType(param);
}
const getList = (type) =>{
const param = {
val:inpValue,
type:type,
}
return API.getList(param);
}
const handleSearch = async ()=>{
const res = await getType();
const type = res?.data?.type;
const res1 = await getList(type);
console.log(res1);
}
return (
<div>
<input
type="text"
value={inpValue}
onChange={(e) => {
setInpValue(e.target.value);
}}
/>
<button
onClick={() => {
handleSearch();
}}
>
Recherche
</button>
</div>
);
}
export default SearchComponent;
Copier le Code
Après avoir changé le composant fonctionnel ,Essaie encore.,Pas d'erreur.,BUGRéparé. Ce n'est qu'après avoir examiné les données que j'ai appris les événements dans les composants fonctionnels. stateEtprops La valeur obtenue est celle utilisée pour le rendu de page au moment où l'événement déclenche stateEtpropsValeur de. Après avoir cliqué sur le bouton recherche ,val
La valeur de est la valeur dans la zone d'entrée à ce moment - là , Peu importe comment la valeur derrière la zone d'entrée change , Les dernières valeurs ne sont pas saisies .
Alors pourquoi les composants , Accès aux derniers stateEt la valeur?? La clé est que les composants de la classe passent par this
Pour obtenirstateDe,Etthis
Toujours la dernière instance de composant .
En fait, changez - le dans un composant de classe , Ça pourrait aussi arranger ça. BUG, Les changements sont les suivants: :
getType (val) {
const param = {
val,
}
return API.getType(param);
}
getList(val,type){
const param = {
val,
type,
}
return API.getList(param);
}
async handleSearch() {
const inpValue = this.state.inpValue;
const res = await this.getType(inpValue);
const type = res?.data?.type;
const res1 = await this.getList(inpValue,type);
console.log(res1);
}
Copier le Code
Recherche d'événements handleSearch
Quand ça se déclenche, Juste la valeur de la zone d'entrée this.state.inpValue
ExisteinpValue
Dans la variable, Les événements suivants doivent être exécutés avec la valeur de la zone d'entrée inpValue
Prise de variables, L'entrée ultérieure dans la zone d'entrée n'affecte pas inpValue
Valeur de la variable, À moins que l'événement de recherche ne soit déclenché à nouveau handleSearch
. Cette modification peut également résoudre ce problème BUG.
InReact Il est essentiel de bien comprendre les concepts et les rôles des composants contrôlés et non contrôlés. , Parce qu'il y a trop de place .
InVueOui.v-model
Les instructions peuvent facilement associer les composants aux données ,EtReact Aucune directive de ce type , Comment relier les composants aux données , Le concept de composants contrôlés est utilisé .
Composants contrôlés, Je comprends que l'état des composants est contrôlé par les données , La façon dont ces données sont modifiées n'est pas un composant , Les composants dont il est question ici ne sont pas seulement des composants , Peut également représenter un natif DOM.Comme uninputZone d'entrée.
input État de la zone d'entrée (Saisissez la valeur de la case) Données value
Contrôle,Modifier les donnéesvalue
MéthodesetValue
Non, pas du tout.input La boîte d'entrée elle - même .
import React, { useState } from "react";
const Input = () =>{
const [value,setValue] = useState('');
return (
<div>
<input
type="text"
value={value}
onChange={(e) => {
setValue(e.target.value);
}}
/>
</div>
);
}
export default Input;
Copier le Code
Comme dansAnt Design UIDansForm Lorsqu'un composant personnalise un contrôle de formulaire , Exiger que le contrôle du formulaire personnalisé accepte les propriétés value
EtonChange
,Parmi euxvalue
Comme valeur pour un contrôle de formulaire personnalisé ,onChange
Événements pour modifier les propriétés value
.
import React from 'react';
import { Form, Input } from 'antd';
const MyInput = (props) => {
const { value, onChange } = props;
const onNameChange = (e) => {
onChange?.(e.target.value)
}
return (
<Input
type="text"
value={value || ''}
onChange={onNameChange}
/>
)
}
const MyForm = () => {
const onValuesChange = (values) => {
console.log(values);
};
return (
<Form
name="demoFrom"
layout="inline"
onValuesChange={onValuesChange}
>
<Form.Item name="name">
<MyInput />
</Form.Item>
</Form>
)
}
export default MyForm;
Copier le Code
Je pense que le plus grand effet des composants contrôlés est lorsque l'état des composants tiers change souvent de façon inexplicable. , Envelopper avec un composant parent , Passer dans un état à contrôler et changer la méthode d'état props, Renvoie l'état du composant au composant parent pour le contrôle , De cette façon, lorsque l'état d'un composant change, il est clair où l'état du composant change. .
Un composant non contrôlé est un composant dont l'état est entièrement contrôlé par lui - même. , Est relatif à un composant ,Par exemple,input Boîte d'entrée InputContrôle des composants,EtInput Composant non soumis DemoContrôle des composants,AlorsInputRelativementDemo Le composant est un composant non contrôlé .
import React, { useState } from "react";
const Input = () =>{
const [value,setValue] = useState('');
return (
<div>
<input
type="text"
value={value}
onChange={(e) => {
setValue(e.target.value);
}}
/>
</div>
);
}
const Demo = () =>{
return (
<Input/>
)
}
export default Demo;
Copier le Code
Les composants non contrôlés peuvent également être considérés comme des composants dont les valeurs ne peuvent être définies que par l'utilisateur. , Ne peut pas être contrôlé par Code . Et rappelez - vous une chose très spéciale DOMÉlément<input type="file" />
, Il ne peut pas définir les fichiers téléchargés par Code .
useState
C'est le plus souvent utilisé. Hook, Partagez ce que vous avez utilisé 3 Une expérience. .
useState
Peut recevoir une fonction comme argument , Appelez cette fonction stateInitialiser la fonction
Scénario général useState
Il suffit de passer une valeur comme ceci stateValeur initiale de, Mais si cette valeur doit être calculée ? Vous pouvez passer dans une fonction , Après le calcul en fonction , Renvoie une valeur initiale .
import React, { useState } from 'react';
export default (props) => {
const { a } = props;
const [b] = useState(() => {
return a + 1;
})
return (
<div>{b}</div>
)
};
Copier le Code
state Mettre à jour comment utiliser l'ancien state
Au début, Je l'utilise comme ça.
const [a , setA] = useState(1);
const changeA = () =>{
setA(a + 1);
}
Copier le Code
J'ai rencontré une erreur. ,Les codes sont les suivants:
const [a , setA] = useState(1);
const changeA = () =>{
setA(a + 1);
setA(a + 1);
}
Copier le Code
Deux appels consécutifs en fonction setA
On verra.a
Toujours égal à2, Pas égal à 3. C'est ce qu'il faut appeler.
const [a , setA] = useState(1);
const changeA = () =>{
setA( a => a+1 );
setA( a => a+1 );
}
Copier le Code
Comment diviserstate
Dans un composant fonctionnel ,Juste unstate Le changement provoque le rendu des composants .EtReact Tant que le composant parent rend à nouveau , Ses sous - composants sont rendus à nouveau .
Alors la question se pose.,Si vous mettezstateDiviser en plusieurs, Lorsque vous changez ces state, Le rendu des composants est déclenché plusieurs fois .
Si elle n'est pas diviséestate,ChangementstateHeure, Ne déclenchera le rendu des composants qu'une seule fois .Mais attention, Les composants fonctionnels ne sont pas comme les composants de classe , Changer state Une des données ,Mise à jour automatiquestateDonnées correspondantes dans. C'est ce qu'il faut faire.
const [data,setData] = useState({a:1,b:2,c:3});
const changeData = () =>{
setData(data =>{
...data,
a:2,
})
}
Copier le Code
Bien sûr que non. state, Cela réduit considérablement la réutilisabilité du Code .Mon expérience est:
Sera totalement sans rapport state Diviser en un .
Si certainsstate Sont interreliées , Ou besoin de changer ensemble , Alors fusionnez - le en un state.
useCallback(fn,[a, b]);
useMemo(fn, [a, b]);
Copier le Code
Comme indiqué ci - dessus,useMemo
Etusebcallback
Dans les paramètresfn
C'est une fonction,Dans les paramètres[a,b]
Dea
Etb
C'est possible.stateOuprops.
useMemo
Etusebcallback
Lors de la première exécution,Mise en œuvrefn
Après cela, créez un cache et retournez - le ,Écouter[a,b]
Représentation enstateOupropsDea
Etb
, Renvoie directement le cache si la valeur n'a pas changé , Exécuter à nouveau si la valeur change fn
Créer un autre cache et le retourner .
useMemo
Etusebcallback
Renvoie un cache , Mais ce cache est différent ,useMemo
Renvoie une valeur, Cette valeur peut être considérée comme une exécution fn
Retour à.usebcallback
Renvoie une fonction, Cette fonction peut être considérée comme fn
. Alors, faites attention. useMemo
Defn
Doit renvoyer une valeur .
React.memo
Pour utiliserAvecReact.memo
Envelopper un composant,Quand le composantprops Ne pas rendre à nouveau tant que des changements ne se sont pas produits .
Si le composant enveloppé est un composant fonctionnel , Dans laquelle useState
、useReducer
、useContext
De Hook,Quandstate OucontextEn cas de changement,Il rend encore, Mais ça n'a pas beaucoup d'impact. ,UtiliserReact.memo
Le but principal de la mise à jour des composants parents est de contrôler les problèmes de mise à jour des composants enfants. .
props Le type de valeur peut être String、Boolean、Null、undefined、Number、Symbol、Object、Array、Function, En termes simples, il s'agit du type de base et du type de référence. .
Pour deux types de données de base ayant des valeurs égales ==
Comparer les retourstrue
, Ces deux types de données de référence de valeur égale sont utilisés ==
Comparer les retoursfalse
, Non, essayez le code suivant. , C'est tout. false
.
console.log({a:1} == {a:1});
console.log([1] == [1]);
const fn1 = () =>{console.log(1)};
const fn2 = () =>{console.log(1)};
console.log(fn1 == fn2);
Copier le Code
C'est pourquoi,Quandprops Lorsque la valeur de est un type de référence , Et cette valeur est calculée par fonction ,AvecuseMemo
Ouusebcallback
On s'en occupe. , Éviter l'égalité des valeurs calculées , Mais les comparaisons ne sont pas égales , Provoque une mise à jour des composants .Je pense queusebcallback
Est spécialement conçu pour le traitement props Valeur créée pour la fonction Hook.
Dans l'exemple suivant ,List Le composant est un composant coûteux à rendre ,Il a deux propriétés,Parmi euxdata
La propriété est la source de données de la liste rendue ,C'est un tableau,onClick
La propriété est une fonction .InDemoIntroduction dans les composantsListComponents,AvecuseMome
Traitementdata
Valeur de l'attribut,AvecuseCallback
TraitementonClick
Valeur de l'attribut,De faireList La question de savoir si le composant est rendu à nouveau n'est soumise qu'à DemoComponentdata
C'eststateContrôle.
ListComponents:
import React from 'react';
const List = (props) => {
const { onClick, data } = props;
//...
return (
<>
{data.map(item => {
return (
<div onClick={() =>{onClick(item)}} key={item.id}>{item.content}</div>
)
})}
</>
)
}
export default React.memo(List);
Copier le Code
DemoComponents:
import
React,
{ useState, useCallback, useMemo }
from 'react';
import List from './List';
const Demo = () => {
//...
const [data, setData] = useState([]);
const listData = useMemo(() => {
return data.filter(item => {
//...
})
}, [data])
const onClick = useCallback((item) => {
console.log(item)
}, []);
return (
<div>
<List onClick={onClick} data={listData} />
</div>
)
}
export default Demo;
Copier le Code
VisibleuseMemo
Etusebcallback
Comme moyen d'optimisation des performances , Peut être résolu dans une certaine mesure React Mise à jour du composant parent , Problèmes de rendement dont les sous - composantes sont également mises à jour .
HypothèsesList Composant non utilisé React.memo
Le paquet,Ça marche.useMemo
Ouusebcallback
Pour optimiser ?Regardez d'abord un morceau de code, Les composants peuvent également être utilisés de la même manière .
import React, { useState } from 'react';
import List from './List';
export default function Demo() {
//...
const [data, setData] = useState([]);
const list = () => {
const listData = data.filter(item => {
//...
})
const onClick = (item) => {
console.log(item)
}
return (
<List onClick={onClick} data={listData} />
)
}
return (
<div>
{list()}
</div>
)
}
Copier le Code
Parmi euxlist
Retour à unReactÉlément,Est une valeur, Ça marche? useMemo
On s'en occupe. .
import React, { useState, useMemo } from 'react';
import List from './List';
export default function Demo() {
//...
const [data, setData] = useState([]);
const listMemo = useMemo(() => {
const listData = data.filter(item => {
//...
})
const onClick = (item) => {
console.log(item)
}
return (
<List onClick={onClick} data={listData} />
)
}, [data])
return (
<div>
{listMemo}
</div>
)
}
Copier le Code
listMemo
Cette valeur(ReactÉlément) Régénérer uniquement par DemoComponentdata
C'eststateContrôle. Ce n'est pas assez. List La question de savoir si le composant est rendu à nouveau n'est soumise qu'à DemoComponentdata
C'eststateContrôle.
Je ne crois pas.“Quoi qu'il arrive,Prends - le.
useMemo
OuuseCallback
On s'en occupe., Pour éviter les problèmes de performance ”
Reconnaître queuseMemo
EtuseCallback
Il y a aussi des frais généraux de calcul ,Par exempleuseMemo
Certaines valeurs sont mises en cache , Rendu ultérieur , Extraire les valeurs du tableau de dépendance pour les comparer aux valeurs enregistrées précédemment , Exécuter à nouveau la fonction de rappel si elle n'est pas égale , Sinon, renvoie directement la valeur mise en cache . Ce processus a des frais généraux de calcul .
Donc il est utiliséuseMemo
EtuseCallback
Assurez - vous d'envisager d'utiliser le scénario avant , Ne pas abuser .
Voici un résumé à utiliser useMemo
EtuseCallback
Scènes:
Lorsque l'attribut d'un composant avec des frais généraux de rendu est une fonction ,AvecuseCallback
Gérer cette valeur de propriété .
Obtenir une valeur, Il y a beaucoup de frais généraux de calcul ,AvecuseMemo
On s'en occupe..
Une valeur calculée pour un type de référence , Et cette valeur est attribuée à l'attribut d'un composant avec des frais généraux de rendu élevés ,AvecuseMemo
On s'en occupe..
PersonnalisationHook Valeur du type de référence exposé dans ,AvecuseMemo
On s'en occupe..
En un mot useMemo
EtuseCallback
Il s'agit de maintenir l'égalité des références et d'éviter les calculs coûteux en double. .
useEffect(fn);
useLayoutEffect(fn);
Copier le Code
useEffect
C'est le deuxième plus souvent utilisé. Hook,useLayoutEffect
Faible fréquence d'utilisation . Voici quatre expériences d'utilisation :
En serviceuseEffect
EtuseLayoutEffect
Avant, Pour comprendre ce qui arrive à ces deux - là. Hook Quand les fonctions de .
EntréeuseEffect
La fonction de ReactTerminé.DOMChangement de, Le navigateur a modifié DOMRenduAprès l'exécution.
EntréeuseLayoutEffect
La fonction de ReactTerminé.DOMDeAprès le changement, Le navigateur a modifié DOMRenduPrécédemment exécuté.
Alors...useEffect
Ne bloque pas le rendu de la page ,useLayoutEffect
Empêche le rendu de la page , Mais si vous voulez obtenir DOM Modifier les propriétés de l'élément ,useLayoutEffect
C'est un bon choix..
Le composant est initialisé et le transfert est effectué à nouveau à chaque mise à jour useEffect
EtuseLayoutEffect
Fonction de. Que voulez - vous faire une fois que le composant est initialisé ?Assez.VueDansmounted
, C'est comme ça que ça se passe. :
useEffect(fn,[]);
useLayoutEffect(fn,[]);
Copier le Code
Comme indiqué ci - dessus useEffect
Passer un tableau vide dans le deuxième paramètre []
Assez.VueDansmounted
,Alors, dansVueDemounted
Souvent utilisé addEventListener
Événements d'écoute,Et aprèsbeforeDestory
Utilisation moyenneremoveEventListener
Supprimer l'écoute des événements.Ça marche.useEffect
Fais - le..
useEffect(() => {
window.addEventListener('keypress', handleKeypress, false);
return () => {
window.removeEventListener('keypress', handleKeypress, false);
};
},[])
Copier le Code
C'est pour écouter les événements du clavier. , Mais vous trouverez un phénomène étrange , Certaines pages s'exécutent lorsqu'elles sont retournées handleKeypress
Méthodes, Certaines pages sont exécutées plusieurs fois après le retour du chariot handleKeypress
Après la méthode, Il n'est plus exécuté. .
C'est à cause d'unuseEffect
Exécuter le précédent avant l'exécution useEffect
De la fonction entrante Renvoie la fonction, Cette fonction de retour peut être utilisée pour Débloquer,Demande d'annulation, Prévenir les fuites de mémoire .
En outre, lors du déchargement des composants ,Sera également exécutéuseEffect
De la fonction entrante Renvoie la fonction.
Le schéma est le suivant: :
window.addEventListener('keypress', handleKeypress, false); // Lancez le premiereffect
window.removeEventListener('keypress', handleKeypress, false);// Effacer le précédenteffect
window.addEventListener('keypress', handleKeypress, false); // Lancez la prochaine effect
window.removeEventListener('keypress', handleKeypress, false); // Effacer le précédenteffect
window.addEventListener('keypress', handleKeypress, false); // Lancez la prochaineeffect
window.removeEventListener('keypress', handleKeypress, false); // Effacer le derniereffect
Copier le Code
C'est pour ça qu'il faut régler ça. BUG,Il suffit deuseEffect
Le deuxième paramètre de .C'est comme ça.VueDansmounted
C'est différent.
InuseEffect
EtuseLayoutEffect
Le deuxième argument pour est un tableau , Appelé dépendance , Exécute la fonction entrante lorsque la dépendance change .
Comme écouter. a
C'eststate Et b
C'estprop, C'est comme ça que ça se passe. :
useEffect(fn,[a,b]);
useLayoutEffect(fn,[a,b]);
Copier le Code
Mais attention à ne pas trop écouter en même temps. stateOuprop,C'est - à - direuseEffect
Trop de dépendance , Si vous en avez trop, optimisez - le. , Sinon, ça mène à ça. useEffect
Difficile à entretenir.
C'est comme ça que je l'optimise. :
useEffect
Diviser en unités plus petites ,ChaqueuseEffect
Dépend du tableau de dépendance respectif .Ce sont les cinq points que j'ai le plus impressionné en six mois. , Il y a une fosse piétinée. , Il y a une courtepointe. leader Code de tuile . Mais le plus gros gain est l'augmentation des salaires. 120%,Ha ha ha, Vous devez sortir de votre zone de confort. , Pour avoir une meilleure récolte .
Bien que les gains ci - dessus puissent être considérés comme plus simples par certains chercheurs , Mais pour les nouveaux transferts React Ces connaissances sont utilisées très souvent. , Réfléchis un peu. . S'il y a des erreurs, veuillez les signaler dans vos commentaires. , Ou peut - être qu'il y a de meilleures choses à partager dans les commentaires. .
「Bienvenue dans la section commentaires,Les responsables des NuggetsLe programme Nugget StarAprès l'activité,Envoyer dans la zone de commentaires100Autour du Nugget,Voir l'article de l'événement pour plus de détails sur le tirage au sort」.