- 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
W jednym z komentarzy ktoś zasugerował mi, abym pokazywał jak najwięcej praktycznych przykładów. Inna osoba pytała konkretnie o przykład filtrowania listy na podstawie tekstu wpisywanego w input. Stwierdziłem, że warto skorzystać z tych sugestii. Oto powstaje seria wpisów, które będą się przeplatały z kursem Reacta jako takim. Tutaj będę pokazywał konkretne przykłady i implementacje, bez tłumaczenia teorii. Pierwszym przykładem będzie właśnie taka lista — na razie wersja prosta, ze statycznymi danymi i synchronicznym wyszukiwaniem. Do dzieła!
Plan działania
Chcesz stworzyć listę (np. kontaktów) i wyrenderować ją. Łatwizna. Do tego potrzebujemy input, który będzie wyszukiwarką. Wpisanie czegoś w input ma powodować filtrowanie listy. Dodatkowo jeśli nic nie znaleziono — ma wyświetlić się komunikat. Jeśli nie wiesz, jak to ugryźć to Poznaj React z naszymi szkoleniami!
Myślę, że ten przykład w całości zamknie się w jednym/dwóch komponentach.
HTML
Najpierw sam HTML:
<input type="search">
<ul>
<li>Michał</li>
<li>Ania</li>
<li>Kasia</li>
<li>Tomek</li>
</ul>
No łatwiej chyba się nie da 😉
React.js
Lista użytkowników
Tworzę dwa komponenty: App
oraz UsersList
. UsersList ma być typowym komponentem „głupim” — tzn. jego renderowanie zależy tylko od przekazanych propsów. Przekażę tam tablicę z listą kontaktów już po przefiltrowaniu, którą zmapuję na listę elementów:
const UsersList = ({ users }) => {
return (
<ul>
{users.map(user => <li key={user}>{user}</li>)}
</ul>
);
};
Pamiętaj o dodaniu unikalnego atrybutu key
do każdego elementu zawsze gdy renderowana jest tablica!
A co gdy brak wyników?
Dodaję jeden warunek i renderuję co innego. A więc ostatecznie ten komponent wygląda tak:
const UsersList = ({ users }) => {
if (users.length > 0) {
return (
<ul>
{users.map(user => <li key={user}>{user}</li>)}
</ul>
);
}
return (
<p>No results!</p>
);
};
Komponent App
Logikę filtrowania oraz obsługę zdarzeń zamknę w komponencie App
. Mógłbym się pokusić o dalszy podział na mniejsze komponenty, ale przy tak prostym przykładzie nie widzę w tym sensu. Przefiltrowanych użytkowników przechowuję w state
i przekazuję do UsersList
. Do inputa podpinam obsługę jednego zdarzenia onInput
:
class App extends React.Component {
constructor() {
super();
this.state = {
filteredUsers: allUsers
};
}
render() {
return (
<div>
<input onInput={this.filterUsers.bind(this)} />
<UsersList users={this.state.filteredUsers} />
</div>
);
}
};
Stała allUsers
pochodzi „z zewnątrz” — w sumie nieistotne skąd, bo nie mam tutaj żadnego API, store’a ani nic takiego. Po prostu zdefiniuj ją sobie gdziekolwiek. Przynajmniej w tym przykładzie 🙂
Implementacja filtrowania
Samo filtrowanie sprowadza się do:
- Pobrania wpisywanego tekstu z inputa
- Przefiltrowania tablicy wedle pewnych kryteriów (*)
- Ustawienia
state
Punkt 2 oznaczyłem gwiazdką, bo to będzie jeszcze osobna funkcja. Kroki 1-3 łatwo zaimplementować:
filterUsers(e) {
const text = e.currentTarget.value;
const filteredUsers = this.getFilteredUsersForText(text)
this.setState({
filteredUsers
});
}
Implementacja getFilteredUsersForText
W tym przypadku ta funkcja działa dość prosto. Filtruję zawartość tablicy na podstawie porównania elementu z wpisanym tekstem. Jeśli element zawiera fragment wpisanego tekstu to zostaje 🙂 Ważne: Porównanie jest niezależnie od wielkości znaków:
getFilteredUsersForText(text) {
return allUsers.filter(user => user.toLowerCase().includes(text.toLowerCase()))
}
Rezultat
Ostatecznie stworzona aplikacja wygląda tak:
See the Pen React.js w przykładach: Filtrowanie listy by Michał Miszczyszyn (@mmiszy) on CodePen.
Pytania?
Jak wrażenia? Jeśli masz jakiekolwiek pytania albo coś jest niejasne — pisz w komentarzu! To dla mnie cenna informacja zwrotna.
Jeśli chcesz na bieżąco śledzić kolejne części kursu React.js to koniecznie polub mnie na Facebooku i zapisz się na newsletter.
Ćwiczenie
Ćwiczenie: Jak zmieniłby się kod, gdyby filtrowanie użytkowników działo się np. na backendzie i było asynchroniczne? Czy musiałabyś modyfikować komponent UsersList
? Spróbuj to zaimplementować, przyjmując, że funkcja getFilteredUsersForText
jest asynchroniczna i ma taką postać:
getFilteredUsersForText(text) {
return new Promise(resolve => {
const time = (Math.random() + 1) * 250;
setTimeout(() => {
const filteredUsers = allUsers.filter(user => user.toLowerCase().includes(text.toLowerCase()));
resolve(filteredUsers);
}, time) ;
});
}
Ćwiczenie*: Spróbuj szybko wpisać coś w input. Czy zawsze wyświetlają się poprawne dane? Takie problemy to tzw. race conditions. Czy umiesz je tutaj jakoś rozwiązać? Pamiętaj, że React.js to tylko biblioteka do budowania widoków, a wiedza na temat rozwiązywania ogólnych problemów jest uniwersalna i bardzo przydatna z dowolnym frameworkiem 🙂
- 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