- React.js: Wprowadzenie do kursu od podstaw
- Poznaj React.js
- Pierwszy komponent w React.js
- Props czyli atrybuty w React.js
- Podział na komponenty w React.js
- Klasy jako komponenty React.js
- Interakcja z komponentami React.js
- Stan komponentów React.js
- State w React.js 2
- Metody cyklu życia komponentu w React.js
- React.js w przykładach: filtrowanie statycznej listy
- Tworzenie aplikacji React.js dzięki create-react-app
- React.js na GitHub Pages dzięki create-react-app
- Testowanie aplikacji React.js — podstawy Enzyme
- Testowanie React.js w Enzyme — props, state i interakcje
- Poprawne bindowanie funkcji w React.js
- Odpowiadam na pytania: Babel, ECMAScript, destrukturyzacja, onClick, className
- Komunikacja pomiędzy komponentami w React.js
- Komunikacja z API w React.js
- Formularze w React.js — kontrolowane komponenty
- Formularze w React.js — niekontrolowane komponenty
- Odpowiadam na pytania: props, nawiasy klamrowe, funkcje vs klasy, import react
- TDD w React.js z pomocą react-testing-library
- Flux i Redux: globalny store i jednokierunkowy przepływ danych
- React + Redux — kurs: wprowadzenie i podstawy
- React + Redux — filtrowanie listy, proste selektory
- Projektowanie komponentów: Presentational & Container Components
- Asynchroniczność w Redux: redux-thunk
- Kiedy używać state, a kiedy Redux?
- Nowe metody cyklu życia: getDerivedStateFromProps i getSnapshotBeforeUpdate
- Leniwe ładowanie komponentów w React dzięki import
- Higher Order Reducers — Redux i powtarzanie kodu
- React Hooks — wprowadzenie i motywacja
- React Hooks: useState, czyli stan w komponentach funkcyjnych
- React Hooks: useState — wiele stanów, callbacki i inne niuanse
- React Hooks: useEffect — efekty uboczne w komponencie
- React Hooks a żądania do API
- useReducer — przenoszenie logiki poza komponent
- useMemo, useCallback, czyli rozwiązanie problemów ze zmieniającymi się propsami
- Wady React Hooks
- React Hooks: Piszemy własne hooki!
Czy w React da się ładować komponenty leniwie? A więc masz już sporą aplikację. Chcesz ją jakoś zoptymalizować. Do głowy przychodzi Ci, oczywiście, podział jej na kilka części, które będą ładowane na żądanie, dopiero gdy będą potrzebne — tzw. lazy load. Z pomocą przychodzi operator import(…)
— po prostu!
Operator import(…)
Składni import something from 'something'
używasz na pewno codziennie. W skrócie, powoduje ona, że dana zależność ładowana jest zanim reszta kodu zostanie uruchomiona. W praktyce, jeśli używasz webpacka, cały kod łączony jest w jeden plik (lub kilka) i moduły ładują się synchronicznie.
Ale import
to także operator, który można użyć w sposób podobny do funkcji: import(…)
. Służy on do dynamicznego ładowania modułów na żądanie. Leniwie. I zwraca Promise
. Brzmi dobrze?
Leniwy komponent React
A więc zastanów się jak można by użyć tego operatora do leniwego ładowania komponentów w React:
- Komponent musi się ładować na żądanie, dopiero gdy będzie miał być wyświetlony.
- Mogę stworzyć komponent (np.
AsyncComponent
), który jako prop przyjmie funkcję ładującą komponent, i wyświetli gdy będzie taka potrzeba. - Użyję do tego metody
componentDidMount
orazsetState
i operatoraimport(…)
Tak mniej-więcej wyglądał mój proces myślowy 😉 Do dzieła!
Asynchroniczny komponent
Robię dokładnie to, co napisałem. Tworzę komponent, który po wyświetleniu wywoła przekazaną funkcję (która załaduje komponent) i go wyświetli, gdy już będzie gotowy:
export class AsyncComponent extends React.Component {
state = { Component: null, isLoading: false }; // (1)
componentDidMount() {
if (!this.state.Component && !this.state.isLoading) { // (2)
this.setState({ isLoading: true }, this.loadComponent); // (3)
}
}
}
Początkowy stan (1) — komponentu nie ma, ładowanie się jeszcze nie rozpoczęło. Następnie w componentDidMount
, o ile jeszcze nie ma komponentu i nie jest on właśnie ładowany (2), ustawiam isLoading
na true
i ładuję komponent. Jak wygląda this.loadComponent
?
loadComponent = () => {
this.props.componentProvider().then(Component => { // (4)
this.setState({ Component, isLoading: false }); // (5)
});
};
Wywołuję przekazaną funkcję (4), a gdy komponent się załaduje to ustawiam go w state
(5). Pozostaje tylko render:
render() {
const { Component } = this.state;
if (Component) {
return <Component />;
}
return null;
}
I już!
Operator import(…)
Nowego komponentu używam w taki sposób, z operatorem import()
:
<AsyncComponent
componentProvider={() =>
import("./AnotherComponent").then(module => module.AnotherComponent) /* (6) */
}
/>
Tutaj tkwi cała magia (6). Operator import(…)
załaduje moduł przekazany jako argument i zwróci Promise z tym modułem!
Dodatkowe propsy
Okej, a co jeśli chcesz przekazać do AnotherComponent
jakieś propsy? To prostsze niż się wydaje! Dodaj do AsyncComponent
nowy props, np. o nazwie componentProps
(7) i użyj operator spread (8):
const componentProps = { props: 'lalala', anotherValue: 123 };
<AsyncComponent
componentProps={componentProps} /* (7) */
componentProvider={() =>
import("./AnotherComponent").then(module => module.AnotherComponent)
}
/>
A w samym AsyncComponent
zmieniam tylko metodę render
:
render() {
const { Component } = this.state;
if (Component) {
return <Component {...this.props.componentProps} />; /* (8) */
}
return null;
}
Efekt
Jeśli teraz zajrzysz do zakładki Network to zobaczysz tam dodatkowe żądanie — np. o nazwie 1.chunk.js
. To właśnie to!
Cały kod znajdziesz na GitHubie: github.com/mmiszy/typeofweb-kurs-react/tree/contacts-list-5-async
Podsumowanie
Tajemna wiedza, którą Ci tutaj przekazałem przyda Ci się w bardziej rozbudowanych aplikacjach. Wyobraź sobie na przykład, że Twoje komponenty są leniwie doładowywane gdy zmienia się adres strony — pobierane jest to, co akurat się przyda. Brzmi jak marzenie? 😉 Poznaj React z naszymi szkoleniami!
Jeśli chcesz na bieżąco dowiadywać się o kolejnych częściach kursu React.js to koniecznie śledź mnie na Facebooku i zapisz się na newsletter.
Ćwiczenie
Ćwiczenie: Zrefaktoruj App.jsx
z poprzedniej części tak, aby komponent ContactsList
był ładowany tylko jeśli kontakty są załadowane i jest więcej niż 0 (this.props.contacts
).
- React.js: Wprowadzenie do kursu od podstaw
- Poznaj React.js
- Pierwszy komponent w React.js
- Props czyli atrybuty w React.js
- Podział na komponenty w React.js
- Klasy jako komponenty React.js
- Interakcja z komponentami React.js
- Stan komponentów React.js
- State w React.js 2
- Metody cyklu życia komponentu w React.js
- React.js w przykładach: filtrowanie statycznej listy
- Tworzenie aplikacji React.js dzięki create-react-app
- React.js na GitHub Pages dzięki create-react-app
- Testowanie aplikacji React.js — podstawy Enzyme
- Testowanie React.js w Enzyme — props, state i interakcje
- Poprawne bindowanie funkcji w React.js
- Odpowiadam na pytania: Babel, ECMAScript, destrukturyzacja, onClick, className
- Komunikacja pomiędzy komponentami w React.js
- Komunikacja z API w React.js
- Formularze w React.js — kontrolowane komponenty
- Formularze w React.js — niekontrolowane komponenty
- Odpowiadam na pytania: props, nawiasy klamrowe, funkcje vs klasy, import react
- TDD w React.js z pomocą react-testing-library
- Flux i Redux: globalny store i jednokierunkowy przepływ danych
- React + Redux — kurs: wprowadzenie i podstawy
- React + Redux — filtrowanie listy, proste selektory
- Projektowanie komponentów: Presentational & Container Components
- Asynchroniczność w Redux: redux-thunk
- Kiedy używać state, a kiedy Redux?
- Nowe metody cyklu życia: getDerivedStateFromProps i getSnapshotBeforeUpdate
- Leniwe ładowanie komponentów w React dzięki import
- Higher Order Reducers — Redux i powtarzanie kodu
- React Hooks — wprowadzenie i motywacja
- React Hooks: useState, czyli stan w komponentach funkcyjnych
- React Hooks: useState — wiele stanów, callbacki i inne niuanse
- React Hooks: useEffect — efekty uboczne w komponencie
- React Hooks a żądania do API
- useReducer — przenoszenie logiki poza komponent
- useMemo, useCallback, czyli rozwiązanie problemów ze zmieniającymi się propsami
- Wady React Hooks
- React Hooks: Piszemy własne hooki!
Przyczepię się, ale `import` nie jest operatorem. Lista operatorów w JS dostępna jest tutaj: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
Import klasyfikowany jest jako `statement` (instrukcja – nie wyrażenie) – podobnie jak `while` czy `for`. Tutaj lista: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements
import(…)
jest propozycją do standardu i nie jest statementem. nie jest też operatorem, mimo, że operator przypomina, nie jest też funkcją, mimo, że funkcję przypomina najbardziej (są pewne różnice).Specyfikacja mówi o nim „syntactic form” oraz „expression”.
Obaj się myliliśmy 😛
hmm a jak zbundluje aplikację to dalej to tak zadziała czy webpack i tak wszystko wrzuci do paczki i nic z tego ?
Zobacz na ostatnim screenshocie — przeglądarka dociąga plik o nazwie zakończonej ….chunk.js gdy jest on potrzebny. Tak samo na produkcji.
Gdyby wrzucał wszystko do paczki to jaki byłby sens tego wpisu? 🙂
W tym AsyncComponent nie powinien się znaleźć czasem ComponentWillUnMount?
Powinen!
Moze kurcze troche glupie pytanie ale zadam :
Sciagnalem to repo, dociagnalem przy pomocu npm install wszystko z jsona i chce odpalic npm start i mi jaknu mieli i mieli i nie chce nic zrobic. What the ? 🙁
sprawdzilem ze mam node, npm , yarn