Co to jest Redux: Przewodnik projektanta

Opublikowany: 2022-03-10
Krótkie podsumowanie ↬ Czy wiesz, że prawdziwa siła Redux wykracza poza zarządzanie państwem? Czy chcesz projektować ze zrozumieniem, jak działa Redux? Przyjrzyjmy się dokładniej, co może zrobić Redux, dlaczego robi swoje, jakie są wady i jak odnosi się do projektowania.

Czy słyszałeś o Redux? Co to jest? Proszę nie googlować!

  • „Fantazyjne rzeczy zaplecza”.
  • „Słyszałem o tym, ale nie wiem, co to jest. Może to framework React?
  • „Lepszy sposób przechowywania i zarządzania stanami w aplikacji React”.

Zadałem to pytanie ponad 40 projektantom. Powyższe są ich typowymi odpowiedziami. Wielu z nich zdaje sobie sprawę, że Redux współpracuje z Reactem, a jego zadaniem jest „zarządzanie stanem”.

Ale czy wiesz, co tak naprawdę oznacza to „zarządzanie państwem”? Czy wiesz, że prawdziwa władza Redux wykracza poza zarządzanie państwem? Czy wiesz, że Redux niekoniecznie wymaga działania Reacta ? Czy chcesz dołączyć do dyskusji swojego zespołu (lub przynajmniej do rozmów w trakcie lunchu) o tym, czy używać Redux? Czy chcesz projektować ze zrozumieniem, jak działa Redux?

Za pomocą tego artykułu chciałbym pokazać Wam pełny obraz Redux : co potrafi, dlaczego robi swoje, jakie są wady, kiedy go używać i jaki ma związek z projektowaniem.

Moim celem jest pomoc projektantom takim jak Ty. Nawet jeśli nie napisałeś wcześniej ani jednej linii kodu, myślę, że nadal jest możliwe i korzystne (i zabawne) zrozumienie Redux. Spodziewaj się prostego języka angielskiego i gryzmołów — bez kodu lub abstrakcyjnych rozmów.

Gotowy do jazdy?

Więcej po skoku! Kontynuuj czytanie poniżej ↓

Co to jest Redux?

Na bardzo wysokim poziomie Redux jest narzędziem, którego programiści używają, aby ułatwić sobie życie. Jak wielu z Was mogło słyszeć, jego zadaniem jest „zarządzanie państwem”. Wyjaśnię, co oznacza zarządzanie państwem, kilka rozdziałów później. W tym momencie zostawię cię z tym zdjęciem:

Przebuduj menedżera stanu.
Redux zarządza stanem, ale w tle jest kilka ukrytych mocy. (Ilustracja autorstwa Beebee) (duży podgląd)

Dlaczego powinno Cię to obchodzić?

Redux dotyczy bardziej wewnętrznego działania aplikacji niż jej wyglądu i działania. Jest to dość złożone narzędzie o stromej krzywej uczenia się. Czy to oznacza, że ​​jako projektanci powinniśmy trzymać się od tego z daleka?

Nie. Myślę, że powinniśmy to przyjąć. Projektant samochodów powinien zrozumieć, do czego służy silnik, prawda? Aby skutecznie projektować interfejsy aplikacji, projektanci powinni mieć również solidną wiedzę na temat rzeczy, które kryją się pod maską . Powinniśmy dowiedzieć się, co może zrobić, zrozumieć, dlaczego programiści z niego korzystają, oraz zdawać sobie sprawę z jego zalet i konsekwencji.

„Projekt to nie tylko to, jak wygląda i jak się czuje. Design to sposób, w jaki to działa”.

— Steve Jobs

Co może zrobić Redux?

Wiele osób używa Redux do zarządzania stanem w aplikacjach React. Jest to najczęstszy przypadek użycia w środowisku naturalnym, a Redux poprawia aspekty, w których React nie radzi sobie dobrze (jeszcze).

Jednak wkrótce zobaczysz, że prawdziwa moc Redux wykracza daleko poza to. Zacznijmy od poznania, co tak naprawdę oznacza zarządzanie państwem.

Zarządzanie państwowe

Jeśli nie masz pewności, co oznacza ten „stan”, zastąpmy go bardziej ogólnym terminem: „dane”. Stan to dane, które zmieniają się od czasu do czasu . Stan określa, co jest wyświetlane w interfejsie użytkownika.

Co oznacza zarządzanie państwowe? Ogólnie rzecz biorąc, istnieją trzy aspekty danych, którymi musimy zarządzać w aplikacji:

  1. Pobieranie i przechowywanie danych
  2. Przypisywanie danych do elementów UI
  3. Zmiana danych

Załóżmy, że budujemy stronę ze zdjęciami Dribbble. Jakie dane chcemy wyświetlić na stronie? Zawierają zdjęcie profilowe autora, imię i nazwisko, animowany GIF, liczbę serduszek, komentarze i tak dalej.

Dane na stronie ujęcia dryblingu
Dane na stronie zdjęcia dryblingu (duży podgląd)

Najpierw musimy pobrać wszystkie te dane z serwera w chmurze i gdzieś je umieścić. Następnie musimy faktycznie wyświetlić dane. Musimy przypisać fragmenty tych danych do odpowiednich elementów interfejsu użytkownika, które reprezentują to, co faktycznie widzimy w przeglądarce. Na przykład przypisujemy adres URL zdjęcia profilowego do atrybutu src tagu HTML img :

 <img src='https://url/to/profile_photo'>

Na koniec musimy obsłużyć zmiany w danych. Na przykład, jeśli użytkownik doda nowy komentarz do ujęcia Dribbble lub doda gwiazdkę, musimy odpowiednio zaktualizować kod HTML.

Koordynacja tych trzech aspektów państwa to duża część front-end developmentu, a React w różnym stopniu wspiera to zadanie. Czasami wbudowana funkcja w React działa wystarczająco dobrze. Jednak w miarę jak aplikacja staje się coraz bardziej złożona, jej stan może stać się trudniejszy do zarządzania z samym React. Dlatego wiele osób zaczyna używać Redux jako alternatywy.

Pobieranie i przechowywanie danych

W React dzielimy interfejs użytkownika na komponenty. Każdy z tych elementów można podzielić na mniejsze elementy (patrz „Czym jest React?”).

Strona ze strzałem dryblingu podzielona na elementy
Strona ujęcia dryblingu podzielona na komponenty (duży podgląd)

Jeśli nasz interfejs użytkownika ma taką strukturę, kiedy pobieramy dane i gdzie je przechowywać przed wypełnieniem interfejsu użytkownika?

Wyobraź sobie, że w każdym komponencie mieszka szef kuchni . Pobieranie danych z serwerów jest jak pozyskiwanie wszystkich składników potrzebnych do przygotowania potraw.

Naiwnym sposobem jest pobieranie i przechowywanie danych w dowolnym miejscu i czasie. To tak, jakby każdy kucharz wychodził po warzywa i mięso prosto z odległych farm.

Naiwny sposób: pobierz dane z każdego komponentu.
Naiwny sposób: pobierz dane z każdego komponentu. (Ilustracja autorstwa Beebee) (duży podgląd)

Takie podejście jest marnotrawstwem. Musielibyśmy wielokrotnie wywoływać serwer z wielu komponentów — nawet dla tych samych danych. Kucharze marnowaliby dużo gazu i czasu na podróżowanie tam iz powrotem.

Dzięki Redux pobieramy dane raz i przechowujemy je w centralnym miejscu, wygodnie zwanym „magazynem”. Dane są wtedy gotowe do użycia w dowolnym momencie przez dowolny komponent. Nie różni się to od posiadania w pobliżu supermarketu, w którym nasi kucharze mogą kupić wszystkie składniki. Supermarket wysyła ciężarówki, które luzem przewożą warzywa i mięso z gospodarstw. Jest to o wiele bardziej wydajne niż proszenie pojedynczych kucharzy, aby sami udali się na farmy!

Sklep służy również jako jedyne źródło prawdy. Komponenty zawsze pobierają dane ze sklepu, a nie z innego miejsca. Dzięki temu cała zawartość interfejsu użytkownika jest spójna.

Redux jako centralny magazyn danych.
Redux jako centralny magazyn danych. (Ilustracja autorstwa Beebee) (duży podgląd)

Przypisywanie danych do elementów interfejsu użytkownika

Tylko z Reactem istnieje lepszy sposób pobierania i przechowywania danych. Możemy poprosić naszego bardzo miłego szefa kuchni Shotwella o zrobienie zakupów dla wszystkich swoich przyjaciół kucharzy. Jeździł ciężarówką na farmy i przywoził smakołyki. Moglibyśmy pobrać dane z komponentu kontenera, na przykład komponentu „Shot” w przykładzie Dribbble, i użyć go jako jedynego źródła prawdy.

Pobierz dane z głównego komponentu.
Pobierz dane z głównego komponentu. (Ilustracja autorstwa Beebee) (duży podgląd)

Takie podejście jest bardziej wydajne niż naiwny sposób pobierania danych z każdego komponentu. Ale jak Shotwell przekazuje składniki innym szefom kuchni? Jak przekazać dane do komponentów, które faktycznie renderują elementy HTML? Przekazujemy dane z komponentów zewnętrznych do komponentów wewnętrznych, takich jak pałeczka w przekaźniku, aż do momentu, gdy dane dotrą do miejsca przeznaczenia.

Na przykład adres URL awatara autora musi zostać przekazany z „Shot”, do „ShotDetail”, do „Title” i wreszcie do tagu <img> . Jeśli nasi kucharze mieszkają w mieszkaniu, to tak naprawdę wygląda to tak:

Przekazuj dane do komponentów za pomocą rekwizytów.
Przekazuj dane do komponentów za pomocą rekwizytów. (Ilustracja autorstwa Beebee) (duży podgląd)

Aby dostarczyć dane do miejsca docelowego, musielibyśmy zaangażować wszystkie komponenty na ścieżce, nawet jeśli w ogóle nie potrzebują danych. Byłoby naprawdę irytujące, gdyby było wiele pięter!

Co się stanie, jeśli supermarket dostarczy dostawę „od drzwi do drzwi”? Dzięki Redux 1 możemy podłączyć dowolne dane do dowolnego komponentu, nie wpływając w ogóle na inne komponenty, na przykład:

1 Aby być absolutnie dokładnym, jest to kolejna biblioteka o nazwie react-redux , która przekazuje dane komponentom React, a nie samym Redux. Ale ponieważ React-redux po prostu zajmuje się hydrauliką, a ludzie prawie zawsze używają Redux i React-redux razem, myślę, że można to uznać za jedną z zalet Redux.

Podłącz dane do komponentów za pomocą Redux.
Podłącz dane do komponentów za pomocą Redux. (Ilustracja autorstwa Beebee) (duży podgląd)

Uwaga : W najnowszej wersji Reacta (16.3) dostępny jest nowy „kontekstowy” interfejs API, który wykonuje prawie to samo zadanie, jeśli chodzi o podłączanie danych do komponentów. Więc jeśli to jedyny powód, dla którego Twój zespół używa Redux, poważnie rozważ aktualizację do React 16.3! Sprawdź oficjalny dokument, aby uzyskać więcej informacji (ostrzeżenie: dużo kodu przed nami).

Zmiana danych

Czasami logika aktualizacji danych w aplikacji może być dość złożona. Może to obejmować wiele etapów, które są od siebie zależne. Przed aktualizacją stanu aplikacji może być konieczne poczekanie na odpowiedzi z wielu serwerów. Być może będziemy musieli zaktualizować wiele miejsc w stanie w różnym czasie i w różnych warunkach.

To może być przytłaczające, jeśli nie mamy dobrej struktury dla całej tej logiki. Kod byłby trudny do zrozumienia i utrzymania.

Redux pozwala nam dzielić i podbijać . Zapewnia standardowy sposób rozbicia logiki aktualizacji danych na małe „reduktory”. Reduktory te harmonijnie współpracują ze sobą, aby zrealizować złożone działanie.

Podziel złożoną logikę na reduktory.
Podziel złożoną logikę na reduktory. (Ilustracja autorstwa Beebee) (duży podgląd)

Miej jednak oko na ostatni rozwój Reacta. Podobnie jak w przypadku API „kontekstowego”, w przyszłej wersji Reacta może pojawić się nowe API „setState”. Ułatwiłoby to rozbicie złożonej logiki aktualizacji na mniejsze części. Gdy ten nowy interfejs API stanie się dostępny, możliwe, że nie będziesz już potrzebował Redux do zarządzania tym aspektem zarządzania stanem.

Prawdziwa moc Redux

Jak dotąd wydaje się, że Redux jest tylko opatrunkiem dla Reacta. Ludzie używają Redux do ulepszania aspektów, których React nie radzi sobie (jeszcze) dobrze. Ale React szybko nadrabia zaległości! W rzeczywistości Dan Abramov, twórca Redux, dołączył do głównego zespołu React na Facebooku kilka lat temu. Byli zajęci pracą nad wyżej wymienionymi ulepszeniami Reacta: kontekstowym API (wydanym w 16.3), lepszym API do pobierania danych (wydemonstrowanym w lutym 2018), lepszym API setState i tak dalej.

Czy to sprawi, że Redux stanie się przestarzały?

Zgadnij co? Nie pokazałem jeszcze prawdziwej mocy Redux!

Moc redux wykracza daleko poza zarządzanie państwem.
Władza Redux wykracza daleko poza zarządzanie państwem. (Ilustracja autorstwa Beebee) (duży podgląd)

Redux zmusza deweloperów do przestrzegania kilku ścisłych zasad, które dają Reduxowi dużą moc (tak, moc dyscypliny!):

  1. Wszystkie dane (stan aplikacji) należy opisać w postaci zwykłego tekstu. Powinieneś być w stanie zapisać wszystkie dane długopisem na papierze.
  2. Każda czynność (zmiana danych) musi być opisana czytelnym tekstem. Musisz zapisać, co zrobisz, zanim cokolwiek zmienisz. Nie możesz zmienić danych bez pozostawienia śladu. Ten proces nazywa się „wysyłaniem akcji” w slangu Redux.
  3. Twój kod, który zmienia dane, musi zachowywać się jak formuła matematyczna. Musi zwrócić ten sam wynik przy tych samych danych wejściowych. Kwadrat 4 to zawsze 16, bez względu na to, ile razy go uruchomisz.

Gdy postępujesz zgodnie z tymi zasadami, aby tworzyć aplikacje, dzieje się magia. Umożliwia wiele fajnych funkcji, które w innym przypadku są trudne lub drogie do wdrożenia. Oto kilka przykładów. 2

2 Zebrałem te przykłady z postu Dana Abramova „You Might Not Need Redux” i jego „React Beginner Question Thread”.

Cofnij, Ponów

Popularna funkcja cofania/ponawiania wymaga planowania na poziomie systemu. Ponieważ cofanie/ponawianie musi rejestrować i odtwarzać każdą zmianę danych w aplikacji, należy to uwzględnić w architekturze od samego początku. Gdyby zrobić to po namyśle, wymagałoby to zmiany wielu plików, co jest receptą na niezliczone błędy.

Cofnij, ponów.
Cofnij, ponów. (Ilustracja autorstwa Beebee) (duży podgląd)

Ponieważ Redux wymaga, aby każda czynność była opisana czystym tekstem, obsługa cofania/ponawiania jest prawie darmowa. Instrukcje, jak zaimplementować cofanie / ponawianie z Redux, mieszczą się na prostej stronie.

Środowisko współpracy

Jeśli tworzysz aplikację podobną do Dokumentów Google, w której wielu użytkowników pracuje razem nad złożonym zadaniem, rozważ użycie Redux. Prawdopodobnie zrobi za ciebie dużo podnoszenia ciężarów.

dokumenty google
Dokumenty Google (ilustracja autorstwa Beebee) (duży podgląd)

Redux bardzo ułatwia wysyłanie tego, co dzieje się w sieci. Odbieranie czynności wykonywanych przez innego użytkownika na innym komputerze, ponowne odtwarzanie zmian i łączenie z tym, co dzieje się lokalnie, jest proste.

Optymistyczny interfejs użytkownika

Optymistyczny interfejs użytkownika to sposób na poprawę doświadczenia użytkownika aplikacji. Sprawia, że ​​aplikacja wydaje się reagować szybciej w wolnej sieci. To popularna strategia w aplikacjach, które wymagają odpowiedzi w czasie rzeczywistym, na przykład strzelanka FPS.

optymistyczny interfejs użytkownika
Optymistyczny interfejs użytkownika (ilustracja autorstwa Beebee) (duży podgląd)

Jako prosty przykład, w aplikacji Twitter, gdy klikniesz serce na tweecie, musi poprosić serwer o wykonanie kilku sprawdzeń, na przykład, czy ten tweet nadal istnieje. Zamiast czekać wiele sekund na wynik, aplikacja postanawia oszukiwać! Zakłada, że ​​wszystko jest w porządku i od razu pokazuje pełne serce.

Serce na Twitterze
Serce na Twitterze (ilustracja autorstwa Beebee) (duży podgląd)

To podejście działa, ponieważ przez większość czasu wszystko jest w porządku. Jeśli coś nie jest w porządku, aplikacja cofnie poprzednie aktualizacje interfejsu użytkownika i zastosuje rzeczywisty wynik z serwera, na przykład wyświetli komunikat o błędzie.

Redux obsługuje optymistyczny interfejs użytkownika w taki sam sposób, jak w przypadku cofania i ponawiania. Ułatwia rejestrowanie, odtwarzanie i cofanie zmian danych w przypadku otrzymania negatywnego wyniku z serwera.

Utrzymywanie się i uruchamianie ze stanu

Redux ułatwia zapisywanie tego, co dzieje się w aplikacji w pamięci. Później, nawet po ponownym uruchomieniu komputera, aplikacja może załadować wszystkie dane i kontynuować pracę z dokładnie tego samego miejsca, tak jakby nigdy nie zostało przerwane.

Zapisz/załaduj postęp gry
Zapisuj/ładuj postęp gry (ilustracja autorstwa Beebee) (duży podgląd)

Jeśli tworzysz grę z Redux, potrzebujesz tylko kilku linijek kodu, aby zapisać/załadować postęp gry, bez zmiany reszty kodu.

Naprawdę rozszerzalne systemy

W przypadku Redux musisz „wysłać” akcję, aby zaktualizować dowolne dane w aplikacji. To ograniczenie umożliwia podłączenie się do prawie każdego aspektu tego, co dzieje się w aplikacji.

Możesz tworzyć naprawdę rozszerzalne aplikacje, w których każda funkcja może być dostosowana przez użytkownika. Na przykład sprawdź Hyper, aplikację terminalową zbudowaną z Redux. Rozszerzenie „hiperpower” dodaje krople do kursora i wstrząsa oknem. Jak ci się podoba ten tryb „wow”? (Być może niezbyt przydatne, ale wystarczająco, by zaimponować użytkownikom)

Tryb „wow” w Hyper, aplikacji terminalowej.
Tryb „wow” w Hyper, aplikacji terminalowej. (duży podgląd)

Debugowanie podróży w czasie

Co powiesz na możliwość podróżowania w czasie podczas debugowania aplikacji? Uruchamiasz aplikację, przewijasz kilka razy do tyłu lub do przodu, aby znaleźć dokładne miejsce wystąpienia błędu, naprawić błąd i ponownie odtworzyć, aby potwierdzić.

Redux spełnia to marzenie programistów. Redux DevTools pozwala manipulować postępem uruchomionej aplikacji jako wideo YouTube — przeciągając suwak!

Jak to działa? Pamiętasz trzy surowe zasady, które wymusza Redux? To sekretny sos magii.

Podróże w czasie w Redux DevTools
Podróże w czasie w Redux DevTools Duży podgląd

Zautomatyzowane raporty o błędach

Wyobraź sobie: użytkownik znajduje coś nie tak w Twojej aplikacji i chce zgłosić błąd. Skrupulatnie wspomina i opisuje, co zrobiła. Deweloper próbuje następnie ręcznie wykonać kroki, aby sprawdzić, czy błąd wystąpi ponownie. Raport o błędzie może być niejasny lub niedokładny. Deweloper ma trudności ze znalezieniem miejsca, w którym znajduje się błąd.

A teraz jak o tym. Użytkownik klika przycisk „Zgłoś błąd”. System automatycznie wysyła do programisty to, co zrobiła. Deweloper klika przycisk „Odtwórz błąd” i obserwuje, jak dokładnie dzieje się ten błąd. Błąd jest zgnieciony na miejscu, wszyscy są szczęśliwi!

Dokładnie tak się stanie, jeśli użyjesz Redux Bug Reporter. Jak to działa? Ograniczenia Redux czynią cuda.

Zautomatyzowane raporty o błędach
Zautomatyzowane raporty o błędach (ilustracja autorstwa Beebee) (duży podgląd)

Wady Redux

Trzy główne zasady, które wymusza Redux, to miecz obosieczny. Umożliwiają zaawansowane funkcje, ale jednocześnie powodują nieuniknione wady.

Stroma krzywa uczenia się

Redux ma stosunkowo stromą krzywą uczenia się. Zrozumienie, zapamiętanie i przyzwyczajenie się do jego wzorców wymaga czasu. Nie zaleca się jednoczesnego uczenia Redux i React, jeśli są one dla Ciebie nowe.

Kod „Boilerplate”

W wielu przypadkach korzystanie z Redux oznacza pisanie większej ilości kodu. Często wymagane jest dotknięcie wielu plików, aby prosta funkcja działała. Ludzie narzekają na kod „boilerplate”, który musieliby napisać w Redux.

Wiem, brzmi to sprzecznie. Czy nie powiedziałem, że Redux umożliwia implementację funkcji przy minimalnym kodzie ? To trochę jak używanie zmywarki. Najpierw trzeba by poświęcić czas na staranne ułożenie naczyń w rzędach. Dopiero wtedy zobaczysz zalety zmywarki: oszczędność czasu na faktyczne mycie naczyń, odkażanie naczyń itp. Musisz zdecydować, czy czas na przygotowanie jest tego wart!

Kara za wyniki

Redux może również mieć wpływ na wydajność ze względu na ograniczenia, które wymusza. Dodaje trochę narzutu za każdym razem, gdy dane się zmieniają. W większości przypadków to nic wielkiego, a spowolnienie nie jest zauważalne. Mimo to, gdy w sklepie znajduje się duża ilość danych i dane często się zmieniają (np. gdy użytkownik szybko pisze na urządzeniu mobilnym), interfejs użytkownika może w rezultacie stać się powolny.

Bonus: Redux to nie tylko reakcja

Powszechnym błędnym przekonaniem jest to, że Redux jest przeznaczony tylko dla Reacta. Wygląda na to, że Redux nie może nic zrobić bez Reacta. Rzeczywiście, Redux uzupełnia React na kilka ważnych sposobów, o czym mówiliśmy wcześniej. To najczęstszy przypadek użycia.

Jednak w rzeczywistości Redux może współpracować z dowolnymi frameworkami front-end, takimi jak Angular, Ember.js, a nawet jQuery, a nawet vanilla JavaScript. Spróbuj googlować, znajdziesz to, to, to, a nawet to. Ogólne idee Redux mają zastosowanie wszędzie!

Tak długo, jak mądrze korzystasz z Redux, możesz czerpać z niego korzyści w wielu sytuacjach — nie tylko w aplikacji React.

Redux działa dobrze z innymi bibliotekami front-end
Redux działa dobrze z innymi bibliotekami front-end. (Ilustracja autorstwa Beebee) (duży podgląd)

Wniosek

Jak każde narzędzie, Redux oferuje kompromis. Udostępnia zaawansowane funkcje, ale ma też nieuniknione wady. Zadaniem zespołu programistów jest ocena, czy kompromis jest tego wart i podjęcie świadomej decyzji.

Jako projektanci, jeśli zrozumiemy zalety i wady Redux, będziemy mogli przyczynić się do tego procesu decyzyjnego z perspektywy projektowania. Na przykład, może moglibyśmy zaprojektować interfejs użytkownika, aby złagodzić potencjalny wpływ na wydajność? Być może moglibyśmy zalecić włączenie funkcji cofania/ponawiania, aby usunąć mnóstwo okien dialogowych potwierdzających? Być może moglibyśmy zaproponować optymistyczny interfejs użytkownika, ponieważ poprawia on wrażenia użytkownika przy stosunkowo niskich kosztach?

Poznaj zalety i ograniczenia technologii i odpowiednio zaprojektuj. Myślę, że to właśnie Steve Jobs miał na myśli, mówiąc: „Projekt to sposób, w jaki to działa”.