React-Tutorial: Komponenten, Hooks und Performance
Veröffentlicht: 2022-03-11Wie bereits im ersten Teil unseres React-Tutorials erwähnt, ist der Einstieg in React relativ einfach. Beginnen Sie mit der Verwendung der Create React App (CRA), initiieren Sie ein neues Projekt und beginnen Sie mit der Entwicklung. Leider können Sie im Laufe der Zeit in eine Situation geraten, in der Ihr Code ziemlich schwer zu warten ist, insbesondere wenn Sie neu bei React sind. Komponenten können unnötig groß werden oder Sie könnten mit Elementen enden, die Komponenten sein könnten, es aber nicht sind, sodass Sie hier und da sich wiederholenden Code schreiben können.
Hier sollten Sie versuchen, Ihre React-Reise wirklich zu beginnen – indem Sie anfangen, in React-Entwicklungslösungen zu denken.
Wann immer Sie sich einer neuen App nähern, einem neuen Design, das Sie später in eine React-Anwendung umwandeln müssen, versuchen Sie zunächst zu entscheiden, welche Komponenten in Ihrer Skizze enthalten sein werden, wie Sie die Skizze trennen können, um sie einfacher zu verwalten, und welche Elemente sind sich wiederholen (oder zumindest ihr Verhalten). Versuchen Sie, das Hinzufügen von Code zu vermeiden, der „in der Zukunft nützlich“ sein könnte – es mag verlockend sein, aber diese Zukunft kommt vielleicht nie und Sie werden diese zusätzliche generische Funktion/Komponente behalten, die viele konfigurierbare Optionen hat.
Auch wenn eine Komponente länger als beispielsweise 2-3 Fensterhöhen ist, lohnt es sich vielleicht, sie zu trennen (wenn möglich) – da sie später einfacher zu lesen ist.
Kontrollierte vs. unkontrollierte Komponenten in React
In den meisten Anwendungen sind Eingaben und Interaktionen mit Benutzern erforderlich, die es ihnen ermöglichen, etwas einzugeben, eine Datei hochzuladen, ein Feld auszuwählen und so weiter. React behandelt die Benutzerinteraktion auf zwei verschiedene Arten – kontrollierte und unkontrollierte Komponenten.
Der Wert gesteuerter Komponenten wird, wie der Name schon sagt, von React gesteuert, indem dem Element, das mit dem Benutzer interagiert, ein Wert bereitgestellt wird, während ungesteuerte Elemente keine Werteeigenschaft erhalten. Dank dessen haben wir eine einzige Quelle der Wahrheit, die zufällig der React-Zustand ist, sodass es keine Diskrepanz zwischen dem gibt, was wir auf dem Bildschirm sehen, und dem, was wir derzeit in unserem Zustand haben. Der Entwickler muss eine Funktion übergeben, die auf die Benutzerinteraktion mit einem Formular reagiert, das seinen Zustand ändert.
class ControlledInput extends React.Component { state = { value: "" }; onChange = (e) => this.setState({ value: e.target.value }); render() { return ( <input value={this.state.value} onChange={this.onChange}/> ); } }
Bei unkontrollierten React-Komponenten ist es uns egal, wie sich der Wert ändert, aber wenn wir den genauen Wert wissen wollen, greifen wir einfach über ref darauf zu.
class UncontrolledInput extends React.Component { input = React.createRef(); getValue = () => { console.log(this.input.current.value); }; render() { return ( <input ref={this.input}/> ); } }
Was sollte also wann verwendet werden? Ich würde sagen, dass kontrollierte Komponenten in den meisten Fällen der richtige Weg sind, aber es gibt einige Ausnahmen. Ein Fall, in dem Sie beispielsweise unkontrollierte Komponenten in React verwenden müssen, ist der file
input, da sein Wert schreibgeschützt ist und nicht programmgesteuert festgelegt werden kann (Benutzerinteraktion erforderlich). Außerdem finde ich kontrollierte Komponenten leichter zu lesen und leichter damit zu arbeiten. Die Validierung für gesteuerte Komponenten basiert auf der Neudarstellung, der Status kann geändert werden, und wir können leicht anzeigen, dass etwas mit der Eingabe nicht stimmt (z. B. Format oder Leerheit).
Ref
Wir haben bereits refs
erwähnt, ein spezielles Feature, das in Klassenkomponenten verfügbar war, bis Hooks in 16.8 auftauchten.
Refs können dem Entwickler Zugriff auf eine React-Komponente oder ein DOM-Element (abhängig vom Typ, an dem wir ref anhängen) durch Referenz gewähren. Es wird als bewährte Vorgehensweise angesehen, sie zu vermeiden und sie nur in Must-Have-Szenarien zu verwenden, da sie das Lesen des Codes etwas erschweren und den Datenfluss von oben nach unten unterbrechen. Dennoch gibt es Fälle, in denen sie notwendig sind, insbesondere bei DOM-Elementen (z. B. programmgesteuertes Ändern des Fokus). Beim Anhängen an ein React-Komponentenelement können Sie Methoden aus dieser Komponente, auf die Sie sich beziehen, frei verwenden. Dennoch sollte diese Praxis vermieden werden, da es bessere Möglichkeiten gibt, damit umzugehen (z. B. Anheben des Zustands und Verschieben von Funktionen in übergeordnete Komponenten).
Refs haben auch drei verschiedene Möglichkeiten, wie sie erreicht werden können:
- Verwenden eines Zeichenfolgenliterals (älter und sollte vermieden werden),
- Verwenden einer Callback-Funktion, die im ref-Attribut festgelegt wird,
- Indem Sie ref als
React.createRef()
und es an eine Klasseneigenschaft binden und darüber zugreifen (beachten Sie, dass Referenzen aus dem Lebenszyklus von componentDidMount verfügbar sind).
Schließlich gibt es Fälle, in denen Referenzen nicht weitergegeben werden, und Zeiten, in denen Sie auf ein tieferes Referenzelement von der aktuellen Komponente zugreifen möchten (z. B. Sie haben eine <Button>
-Komponente, die ein inneres <input>
-DOM-Element hat, und gerade Sie befinden sich in einer <Row>
-Komponente, und von der Zeilenkomponente aus möchten Sie Zugriff auf die Eingabe der DOM-Fokusfunktion haben (dort würden Sie forwardRef
verwenden).
Ein Fall, in dem die Referenz nicht weitergegeben wird, ist, wenn eine Komponente höherer Ordnung auf einer Komponente verwendet wird – der Grund ist ziemlich verständlich, da ref
KEINE prop
ist (ähnlich wie key
), also wird es nicht weitergegeben, also wird es auf die HOC
verweisen, anstatt auf die Komponente, die von ihr umschlossen wird. In einem solchen Fall können wir React.forwardRef
verwenden, das Props und Refs als Argumente akzeptiert, die dann prop
zugewiesen und an die Komponente weitergegeben werden können, auf die wir zugreifen möchten.
function withNewReference(Component) { class Hoc extends React.Component { render() { const {forwardedRef, ...props} = this.props; return <Component ref={forwardedRef} {...props}/>; } } return React.forwardRef((props, ref) => { return <Hoc {...props} forwardedRef={ref} />; }); }
Fehlergrenzen
Je komplexer die Dinge werden, desto höher ist die Wahrscheinlichkeit, dass etwas schief geht. Deshalb sind Fehlergrenzen ein Teil von React. Wie funktionieren sie?
Wenn etwas schief geht und es keine Fehlergrenze als übergeordnetes Element gibt, führt dies dazu, dass die gesamte React-App fehlschlägt. Es ist besser, keine Informationen anzuzeigen, als Benutzer in die Irre zu führen und falsche Informationen anzuzeigen, aber das bedeutet nicht unbedingt, dass Sie die gesamte Anwendung zum Absturz bringen und einen weißen Bildschirm anzeigen sollten. Mit Fehlergrenzen haben Sie ein zusätzliches Maß an Flexibilität, das Sie nutzen können. Sie können eines entweder in der gesamten App verwenden und eine Fehlermeldung anzeigen, oder es in einigen Widgets verwenden und sie einfach nicht anzeigen, oder stattdessen eine kleine Menge an Informationen anstelle dieser Widgets anzeigen.
Denken Sie daran, dass es nur um Probleme mit deklarativem Code geht und nicht um imperativen Code, den Sie für die Behandlung einiger Ereignisse oder Aufrufe schreiben. Für diese sollten Sie immer noch den regulären Try/Catch- Ansatz verwenden.
Fehlergrenzen sind auch ein Ort, an dem Sie Informationen an den von Ihnen verwendeten Fehlerprotokollierer senden können (in der Lebenszyklusmethode „ componentDidCatch
“).
class ErrorBoundary extends React.Component { state = { hasError: false }; static getDerivedStateFromError(error) { return { hasError: true }; } componentDidCatch(error, info) { logToErrorLogger(error, info); } render() { if (this.state.hasError) { return <div>Help, something went wrong.</div>; } return this.props.children; } }
Komponenten höherer Ordnung
Komponenten höherer Ordnung (HOC) werden oft in React erwähnt und sind ein sehr beliebtes Muster, das Sie wahrscheinlich verwenden werden (oder bereits verwendet haben). Wenn Sie mit HOCs vertraut sind, haben Sie wahrscheinlich in vielen Bibliotheken withNavigation, connect, withRouter
gesehen.
HOCs sind nur Funktionen, die eine Komponente als Argument annehmen und eine neue Komponente mit erweiterten Fähigkeiten im Vergleich zu der ohne den HOC-Wrapper zurückgeben. Dadurch können Sie einige leicht erweiterbare Funktionen erreichen, die Ihre Komponenten verbessern könnten (z. B. Zugriff auf die Navigation). HOCs können auch einige Formen annehmen, die abhängig von dem, was wir haben, aufgerufen werden, wobei das einzige Argument, das immer erforderlich ist, eine Komponente ist, aber es kann zusätzliche Argumente annehmen – einige Optionen oder wie in connect
rufen Sie zuerst eine Funktion mit Konfigurationen auf, die später eine Funktion zurückgibt die eine Argumentkomponente nimmt und HOC zurückgibt.
Es gibt ein paar Dinge, die Sie hinzufügen könnten und die Sie vermeiden sollten:
- Fügen Sie einen Anzeigenamen für Ihre Wrapper-HOC-Funktion hinzu (damit Sie wissen, dass es sich tatsächlich um eine HOC handelt, indem Sie den Anzeigenamen Ihrer HOC-Komponente ändern).
- Verwenden Sie HOC nicht innerhalb einer Rendermethode – Sie sollten bereits eine erweiterte Komponente darin verwenden, anstatt dort eine neue HOC-Komponente zu erstellen, da Sie sie ständig neu einhängen und ihren aktuellen Zustand verlieren.
- Statische Methoden werden nicht kopiert. Wenn Sie also einige statische Methoden in Ihrer neu erstellten HOC haben möchten, müssen Sie sie selbst kopieren.
- Die erwähnten Refs werden nicht übergeben, verwenden Sie also
React.forwardRef
wie zuvor erwähnt, um solche Probleme zu lösen.
export function importantHoc() { return (Component) => class extends React.Component { importantFunction = () => { console.log("Very Important Function"); }; render() { return ( <Component {...this.props} importantFunction={this.importantFunction} /> ); } }; }
Styling
Styling hat nicht unbedingt mit React selbst zu tun, ist aber aus mehreren Gründen erwähnenswert.
Zunächst einmal gelten hier ganz normal die regulären CSS/Inline-Stile und Sie können einfach Klassennamen aus CSS in das className-Attribut einfügen, und es wird korrekt funktionieren. Das Inline-Styling unterscheidet sich ein wenig vom regulären HTML-Styling. Die Zeichenfolge wird nicht mit Stilen weitergegeben, sondern mit Objekten mit jeweils korrekten Werten. Style-Attribute sind ebenfalls camelCased, also wird border-radius zu borderRadius und so weiter.
React scheint einige Lösungen populär gemacht zu haben, die nicht nur in name.modules.css
alltäglich geworden sind, wie z , zB WebStorm, haben dafür auch eine Autovervollständigung, die Ihnen sagt, welche Namen verfügbar sind).
Eine andere Lösung, die auch in React beliebt ist, ist CSS-in-JS (z. B. die emotion
). Um es noch einmal zu betonen, CSS-Module und Emotion (oder CSS-in-JS im Allgemeinen) sind nicht auf React beschränkt.
Haken in Reaktion
Hooks sind wahrscheinlich die am sehnlichsten erwartete Ergänzung zu React seit der Neufassung. Wird das Produkt dem Hype gerecht? Aus meiner Sicht ja, da sie wirklich ein tolles Feature sind. Es sind im Wesentlichen Funktionen, die neue Möglichkeiten eröffnen, wie zum Beispiel:
- Ermöglicht das Entfernen vieler
class
, die wir nur verwendet haben, weil wir zB keinen lokalen Zustand oder Verweis haben konnten, damit der Code für eine Komponente leichter lesbar aussieht. - Ermöglicht es Ihnen, weniger Code für denselben Effekt zu verwenden.
- Erleichtert das Nachdenken und Testen von Funktionen, zB durch Verwendung der React-Testing-Library.
- Kann auch Parameter annehmen, und das Ergebnis von einem kann leicht von einem anderen Hook verwendet werden (z. B.
setState
vonuseState
inuseEffect
). - Minimiert viel besser als Klassen, die für Minifier tendenziell etwas problematischer sind.
- Kann HOCs entfernen und Requisitenmuster in Ihrer App rendern, die neue Probleme verursacht haben, obwohl sie zur Lösung anderer entwickelt wurden.
- Kann von jedem erfahrenen React-Entwickler individuell erstellt werden.
Es gibt nur wenige React-Hooks, die standardmäßig enthalten sind. Die drei grundlegenden sind useState
, useEffect
und useContext
. Es gibt auch einige zusätzliche, zB useRef
und useMemo
, aber jetzt konzentrieren wir uns auf die Grundlagen.
Werfen wir einen Blick auf useState
und verwenden wir es, um ein Beispiel für einen einfachen Zähler zu erstellen. Wie funktioniert es? Nun, im Grunde ist das ganze Konstrukt wirklich einfach und sieht so aus:
export function Counter() { const [counter, setCounter] = React.useState(0); return ( <div> {counter} <button onClick={() => setCounter(counter + 1)}>+</button> </div> ); };
Es wird mit initialState
(value) aufgerufen und liefert damit ein Array mit zwei Elementen zurück. Dank der Array-destrukturierenden Zuweisung können wir die Variablen diesen Elementen sofort zuweisen. Der erste ist immer der letzte Zustand nach Aktualisierungen, während der andere eine Funktion ist, die wir verwenden werden, um den Wert zu aktualisieren. Scheint ziemlich einfach, nicht wahr?
Auch aufgrund der Tatsache, dass solche Komponenten früher zustandslose funktionale Komponenten genannt wurden, ist ein solcher Name nicht mehr angemessen, da sie einen Zustand haben können, wie er oben gezeigt wird. Daher scheinen die Namen Klassenkomponenten und Funktionskomponenten eher dem zu entsprechen, was sie tatsächlich tun, zumindest ab 16.8.0.
Die Update-Funktion (in unserem Fall setCounter
) kann auch als Funktion verwendet werden, die den vorherigen Wert als Argument in der folgenden Form verwendet:
<button onClick={() => setCounter(prevCounter => prevCounter + 1)}>+</button> <button onClick={() => setCounter(prevCounter => prevCounter - 1)}>-</button>
Im Gegensatz zur this.setState
, die eine flache Zusammenführung durchführte, überschreibt das Festlegen der Funktion (in unserem Fall setCounter
) stattdessen den gesamten Status.

Außerdem kann initialState
auch eine Funktion sein, nicht nur ein einfacher Wert. Dies hat seine eigenen Vorteile, da diese Funktion nur während des anfänglichen Renderns der Komponente ausgeführt wird und danach nicht mehr aufgerufen wird.
const [counter, setCounter] = useState(() => calculateComplexInitialValue());
Wenn wir schließlich setCounter
mit genau demselben Wert verwenden, den wir im selben Moment im aktuellen Zustand ( counter
) hatten, wird die Komponente nicht neu gerendert.
Auf der anderen Seite geht es bei useEffect
darum, Seiteneffekte zu unserer funktionalen Komponente hinzuzufügen, seien es Abonnements, API-Aufrufe, Timer oder einfach alles, was wir nützlich finden könnten. Jede Funktion, die wir an useEffect
, wird nach dem Rendern ausgeführt, und zwar nach jedem Rendern, es sei denn, wir fügen eine Einschränkung hinzu, welche Eigenschaftenänderungen als zweites Argument der Funktion erneut ausgeführt werden sollen. Wenn wir es nur beim Mounten ausführen und beim Unmounten aufräumen wollen, müssen wir nur ein leeres Array darin übergeben.
const fetchApi = async () => { const value = await fetch("https://jsonplaceholder.typicode.com/todos/1"); console.log(await value.json()); }; export function Counter() { const [counter, setCounter] = useState(0); useEffect(() => { fetchApi(); }, []); return ( <div> {counter} <button onClick={() => setCounter(prevCounter => prevCounter + 1)}>+</button> <button onClick={() => setCounter(prevCounter => prevCounter - 1)}>-</button> </div> ); };
Der obige Code wird aufgrund eines leeren Arrays als zweites Argument nur einmal ausgeführt. Im Grunde ist es in diesem Fall so etwas wie componentDidMount
, aber es wird etwas später ausgelöst. Wenn Sie einen ähnlichen Hook haben möchten, der vor dem Browser-Paint aufgerufen wird, verwenden useLayoutEffect
, aber diese Aktualisierungen werden im Gegensatz zu useEffect
synchron angewendet.
useContext
scheint am einfachsten zu verstehen, da man angibt, auf welchen Kontext wir zugreifen möchten (ein Objekt, das von der Funktion createContext
zurückgegeben wurde) und uns im Gegenzug den Wert für diesen Kontext liefert.
const context = useContext(Context);
Um schließlich Ihren eigenen Hook zu schreiben, können Sie einfach etwas wie das Folgende schreiben:
function useWindowWidth() { let [windowWidth, setWindowWidth] = useState(window.innerWidth); function handleResize() { setWindowWidth(window.innerWidth); } useEffect(() => { window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); return windowWidth; }
Grundsätzlich verwenden wir den regulären useState
Hook, dem wir als Anfangswert die Fensterbreite zuweisen. Dann fügen wir in useEffect,
einen Listener hinzu, der handleResize
bei jeder Fenstergrößenänderung auslöst. Wir löschen auch, nachdem die Komponente ausgehängt wurde (sehen Sie sich die Rückgabe in useEffect
an). Leicht?
Hinweis: Die Wortverwendung in allen Hooks ist wichtig. Es wird verwendet, weil es React erlaubt, zu überprüfen, ob Sie nichts Schlechtes tun, zB Hooks von regulären JS-Funktionen aufrufen.
Typen prüfen
React hatte seine eigene Requisitenprüfung, bevor Flow und TypeScript eine Option waren.
PropTypes überprüft, ob die Eigenschaften (Props), die von einer React-Komponente empfangen werden, und ob sie mit dem übereinstimmen, was wir haben. Immer wenn eine andere Situation eintritt (z. B. Objekt statt Array), erhalten wir eine Warnung in der Konsole. Es ist wichtig zu beachten, dass PropTypes aufgrund ihrer Auswirkungen auf die Leistung und der oben genannten Konsolenwarnung nur im Entwicklungsmodus überprüft werden.
Ab React 15.5 befinden sich PropTypes in einem anderen Paket, das separat installiert werden muss. Sie werden zusammen mit Eigenschaften in einer statischen Eigenschaft namens propTypes
(Überraschung) deklariert, wobei sie mit defaultProps
kombiniert werden, die verwendet werden, wenn die Eigenschaften nicht definiert sind ( undefiniert ist der einzige Fall). DefaultProps sind nicht mit PropTypes verwandt, aber sie können einige Warnungen lösen, die aufgrund von PropTypes auftreten können.
Die anderen beiden Optionen sind Flow und TypeScript, und sie sind heutzutage viel beliebter (insbesondere TypeScript).
- TypeScript ist eine von Microsoft entwickelte typisierte Obermenge von JavaScript, die Fehler überprüfen kann, bevor eine App überhaupt ausgeführt wird, und eine hervorragende Autovervollständigungsfunktion für die Entwicklung bietet. Es verbessert auch das Refactoring erheblich. Aufgrund des Microsoft-Supports, der über umfangreiche Erfahrung mit typisierten Sprachen verfügt, ist dies auch eine ziemlich sichere Wahl.
- Flow ist im Gegensatz zu TypeScript keine Sprache. Es ist ein statischer Typprüfer für JavaScript, daher ähnelt es eher einem Tool, das Sie in JavaScript einbinden, als einer Sprache. Die ganze Idee hinter Flow ist dem, was TypeScript bietet, ziemlich ähnlich. Sie können Typen hinzufügen, sodass es weniger wahrscheinlich ist, dass Fehler auftreten, bevor Sie den Code ausführen. Genau wie TypeScript wird Flow nun von Anfang an in CRA (Create React App) unterstützt.
Ich persönlich finde TypeScript schneller (praktisch verzögerungsfrei), insbesondere bei der automatischen Vervollständigung, die bei Flow etwas langsamer erscheint. Es ist erwähnenswert, dass IDEs wie WebStorm, die ich persönlich verwende, eine CLI für die Integration mit Flow verwenden. Es scheint jedoch noch einfacher zu sein, die optionale Verwendung in Dateien zu integrieren, wo Sie einfach // @flow
am Anfang der Datei hinzufügen, um die Typprüfung zu starten. Soweit ich das beurteilen kann, scheint TypeScript am Ende den Kampf gegen Flow gewonnen zu haben – es ist jetzt viel beliebter und einige der beliebtesten Bibliotheken werden von Flow auf TypeScript umgestaltet.
Es gibt ein paar weitere Optionen, die auch in der offiziellen Dokumentation erwähnt werden, wie Reason (von Facebook entwickelt und in der React-Community immer beliebter), Kotlin (eine von JetBrains entwickelte Sprache) und mehr.
Offensichtlich wäre es für Front-End-Entwickler der einfachste Ansatz, einzusteigen und mit der Verwendung von Flow und TypeScript zu beginnen, anstatt zu Kotlin oder F# zu wechseln. Für Back-End-Entwickler, die auf Front-End umsteigen, sind diese jedoch möglicherweise einfacher für den Einstieg.
Produktion und Reaktionsleistung
Die grundlegendste und offensichtlichste Änderung, die Sie für den Produktionsmodus vornehmen müssen, besteht darin, für DefinePlugin
auf „Produktion“ umzuschalten und im Fall von Webpack UglifyJsPlugin
hinzuzufügen. Im Fall von CRA ist es so einfach wie die Verwendung von npm run build
(das die Ausführung von react-scripts build
). Beachten Sie, dass Webpack und CRA nicht die einzigen Optionen sind, da Sie auch andere Build-Tools wie Brunch verwenden können. Dies wird normalerweise in der offiziellen Dokumentation behandelt, sei es die offizielle React-Dokumentation oder die Dokumentation für ein bestimmtes Tool. Um sicherzustellen, dass der Modus richtig eingestellt ist, können Sie die React Developer Tools verwenden, die Ihnen einen Hinweis darauf geben, welche Art von Build Sie verwenden (Produktion vs. Entwicklung). Durch die oben genannten Schritte wird Ihre Anwendung ohne Überprüfungen und Warnungen ausgeführt, die von React kommen, und das Bundle selbst wird ebenfalls minimiert.
Es gibt noch ein paar weitere Dinge, die Sie für Ihre React-App tun können. Was machen Sie mit der erstellten JS-Datei? Sie können mit nur „bundle.js“ beginnen, wenn die Größe relativ klein ist, oder vielleicht so etwas wie „Anbieter + Bündel“ oder vielleicht „Anbieter + kleinstes erforderliches Teil + Dinge importieren, wenn sie benötigt werden“. Dies ist nützlich, wenn Sie es mit einer sehr großen App zu tun haben und nicht gleich am Anfang alles importieren müssen. Beachten Sie, dass das Bündeln von JavaScript-Code im Hauptpaket, der nicht einmal verwendet wird, einfach die Paketgröße erhöht und das Laden der App ganz am Anfang langsamer macht.
Anbieter-Bundles können nützlich sein, wenn Sie planen, die Versionen von Bibliotheken einzufrieren, wenn Sie feststellen, dass sie sich für eine lange Zeit (wenn überhaupt) nicht ändern werden. Außerdem lassen sich größere Dateien besser gzippen, sodass sich der Vorteil, den Sie aus der Trennung ziehen, manchmal nicht lohnt. Es hängt von der Dateigröße ab und manchmal müssen Sie es einfach selbst ausprobieren.
Code-Splitting
Code-Splitting kann auf mehr Arten als hier vorgeschlagen auftreten, aber konzentrieren wir uns auf das, was wir in CRA und React selbst zur Verfügung haben. Grundsätzlich können wir, um Code in verschiedene Chunks aufzuteilen, import()
verwenden, das dank Webpack funktioniert ( import
selbst ist ab sofort ein Vorschlag in Stufe 3, also noch nicht Teil des Sprachstandards). Immer wenn Webpack import
sieht, weiß es, dass es zu diesem Zeitpunkt mit der Codeaufteilung beginnen muss und es nicht in das Hauptpaket aufnehmen kann (der Code, der sich im Import befindet).
Jetzt können wir es mit React.lazy()
verbinden, was import()
mit einem Dateipfad erfordert, der die Komponente enthält, die an dieser Stelle gerendert werden muss. Als nächstes können wir React.suspense()
verwenden, das an dieser Stelle eine andere Komponente anzeigt, bis die importierte Komponente geladen ist. Man könnte sich fragen; Wenn wir eine einzelne Komponente importieren, warum brauchen wir sie dann?
Das ist nicht ganz der Fall, da React.lazy()
die Komponente anzeigt, die wir import()
, aber import()
könnte einen größeren Teil als diese einzelne Komponente abrufen. Beispielsweise kann diese bestimmte Komponente andere Bibliotheken im Schlepptau, mehr Code usw. haben, sodass eine Datei nicht erforderlich ist – es können viele weitere Dateien gebündelt sein. Schließlich können wir all das in ErrorBoundary
(Sie finden den Code in unserem Abschnitt über Fehlergrenzen) , der als Fallback dient, wenn etwas mit der Komponente, die wir importieren wollten, fehlschlägt (z. B. wenn ein Netzwerkfehler vorliegt).
import ErrorBoundary from './ErrorBoundary'; const ComponentOne = React.lazy(() => import('./ComponentOne')); function MyComponent() { return ( <ErrorBoundary> <React.Suspense fallback={<div>Loading...</div>}> <ComponentOne/> </React.Suspense> </ErrorBoundary> ); }
Dies ist ein einfaches Beispiel, aber Sie können natürlich mehr tun. Sie können import
und React.lazy
für dynamisches Routensplitting verwenden (z. B. Admin vs. normaler Benutzer oder einfach nur sehr große Pfade, die viel bringen). Beachten Sie, dass React.lazy
ab sofort nur Standardexporte und kein serverseitiges Rendern unterstützt.
Leistung des Reaktionscodes
Wenn Ihre React-Anwendung in Bezug auf die Leistung verzögert arbeitet, gibt es zwei Tools, die Ihnen helfen können, das Problem zu lösen.
Der erste ist der Chrome Performance Tab, der Ihnen sagt, was mit jeder Komponente passiert (z. B. Mount, Update). Dank dessen sollten Sie in der Lage sein, festzustellen, welche Komponente Leistungsprobleme aufweist, und diese dann optimieren.
Die andere Option ist die Verwendung von DevTools Profiler, der in React 16.5+ verfügbar wurde, und in Zusammenarbeit mit shouldComponentUpdate (oder PureComponent, das in Teil 1 dieses Tutorials erklärt wurde) können wir die Leistung für einige kritische Komponenten verbessern.
Offensichtlich ist es optimal, grundlegende Best Practices für das Web anzuwenden, wie z. B. das Entprellen einiger Ereignisse (z. B. Scrollen), Vorsicht bei Animationen (Verwenden von Transformationen, anstatt die Höhe zu ändern und zu animieren) und so weiter. Die Verwendung von Best Practices kann sehr leicht übersehen werden, insbesondere wenn Sie sich gerade erst mit React auseinandersetzen.
Der Zustand der Reaktion im Jahr 2019 und darüber hinaus
Wenn wir persönlich über die Zukunft von React sprechen würden, wäre ich nicht allzu besorgt. Aus meiner Sicht wird React 2019 und darüber hinaus keine Probleme haben, seinen Thron zu halten.
React hat ein so starkes Ansehen, unterstützt von einer großen Community, dass es schwierig sein wird, es zu entthronen. Die React-Community ist großartig, ihr gehen die Ideen nicht aus, und das Kernteam arbeitet ständig daran, React zu verbessern, neue Funktionen hinzuzufügen und alte Probleme zu beheben. React wird auch von einem großen Unternehmen unterstützt, aber die Lizenzprobleme sind weg – es ist jetzt MIT-lizenziert.
Ja, es gibt ein paar Dinge, die voraussichtlich geändert oder verbessert werden; zum Beispiel React etwas kleiner machen (eine der genannten Maßnahmen ist das Entfernen synthetischer Ereignisse) oder className
in class.
Natürlich können selbst diese scheinbar geringfügigen Änderungen Probleme verursachen, z. B. die Beeinträchtigung der Browserkompatibilität. Persönlich frage ich mich auch, was passieren wird, wenn WebComponent an Popularität gewinnt, da es einige der Dinge erweitern könnte, mit denen React heute oft verwendet wird. Ich glaube nicht, dass sie ein vollständiger Ersatz sein werden, aber ich glaube, dass sie sich gut ergänzen könnten.
Kurzfristig kamen Hooks gerade zu React. Das ist wahrscheinlich die größte Änderung seit der Umschreibung in React, da sie viele Möglichkeiten eröffnen und weitere Funktionskomponenten verbessern werden (und sie werden jetzt wirklich hochgespielt).
Schließlich, da ich das zuletzt gemacht habe, gibt es React Native. Für mich ist es eine großartige Technologie, die sich in den letzten Jahren so stark verändert hat (das Fehlen eines React-Native-Links war wahrscheinlich das größte Problem für die meisten Menschen, und es gab offensichtlich viele Fehler). Der Kern von React Native wird neu geschrieben, und das sollte auf ähnliche Weise wie bei der Neufassung von React erfolgen (es ist alles intern, nichts oder fast nichts sollte für Entwickler geändert werden). Asynchrones Rendering, eine schnellere und leichtere Brücke zwischen nativem und JavaScript und mehr.
Es gibt viel, worauf man sich im React-Ökosystem freuen kann, aber Updates für Hooks (und React Native, wenn jemand Handys liebt) sind wahrscheinlich die wichtigsten Änderungen, die wir 2019 sehen werden.