[PL] Let’s Write – to działa!

Mamy to! React w końcu zaczął mnie słuchać :D Wymagało to dużo pracy, ale w końcu się udało. Strona zaczyna działać. Na razie nie ma najważniejszej części jednak mamy już coś na czym możemy bazować.

Poprzednie wpisy z serii:

Ścieżka do celu

Miałem trochę kłopotów z uruchomieniem routingu ale już jest. W tym momencie mój plik router.js wygląda tak:

Jest tutaj obsługa głównego layoutu dla wszystkich stron ( <Route path='/' component={MainLayout}> ). Wartość w atrybucie path oznacza, że ta ścieżka powinna być wyświetlona dla wszystkich stron w naszej domenie.

Następnie mamy zagnieżdżone kolejne ścieżki. Pierwsza z nich (  <IndexRoute component={IndexContainer} /> ) odpowiada na wyświetlenie komponentu kiedy użytkownik wpisze tylko naszą domenę bez konkretnej ścieżki. To jest po prostu odpowiednik pliku index.html w tradycyjnych stronach www.

Ostatnia ścieżka obsługuje adres  nasza-domena/login . W tym przypadku wyświetla stronę logowania.

Najwięcej problemów z React-Router miałem z powodu pogubienia się przy wyświetlaniu zagnieżdżonych elementów. Ciągle gdzieś brakowało wywołania  this.props.children . Czasami też robiłem literówki, które trudno było znaleźć :P Chyba będę musiał znowu włączyć JSLint :D

Ważne: w tym momencie aplikacja nie pozwala przejść do konkretnej strony wpisując jej adres w pasku przeglądarki. Wpisując  nasza-domena/login  dostaniemy błąd „404”. Jest to spowodowane tym, że nie mam jeszcze przygotowanego serwera. Korzystam z domyślnych ustawień http-servera, który nie zwraca głównego pliku strony dla każdego adresu. Dlatego teraz można przechodzić między stronami tylko klikając linki w aplikacji.

Jak Ty wyglądasz?!

Poprzednio próbowałem pisać wszystkie style sam. Ostatecznie nie udało się to i teraz korzystam z frameworka. Najpierw próbowałem użyć Material-UI, który wygląda ładnie. Ale używanie go jest bardzo trudne wg mnie. Ciężko cokolwiek zmienić, wiele rzeczy nie działa jak się próbuje używać małych komponentów. Dodatkowo Material-UI korzysta z dziwnego sposobu dołączania motywu.

Po tym jak nic mi nie chciało działać i strona się rozsypywała szybko podjąłem decyzję o wyrzuceniu Material-UI. Od teraz korzystam z React-Bootstrap czyli z biblioteki dającej dostęp do Bootstrapa za pośrednictwem komponentów.

Tak jak mówiłem najpierw zamierzałem się zająć stroną główną. Przez weekend udało mi się zrobić tyle:

Nie jest to oczywiście końcowy efekt, ale pokazuje w którą stronę chcę iść. W tym miejscu polecam darmowe banki zdjęć. To zdjęcie jest bardzo ładne i mogę je używać bez ograniczeń i opłat.

Staram się robić stronę tak, żeby dobrze wyglądała na różnych wielkościach ekranu. Jednak teraz nie trzymam się tego w 100%. Wolę zrobić najpierw coś co działa, a szczegóły wyglądu dopracować na końcu.

Teksty będę wymyślał na koniec.

Jeśli kogoś interesuje kod komponentu strony głównej to wygląda on tak:

React-Bootstrap pozwala pisać przejrzysty kod. W przyszłości podzielę ten widok na mniejsze komponenty.

Akcja!

W projekcie korzystam z Reduxa. Nawet mam już kod, który go wykorzystuje! Na ten moment obsługuję już zmianę stanu użytkownika na zalogowanego albo wylogowanego.

Po wybraniu z menu „Login” przechodzimy do prostej strony logowania:

Na razie dane z formularza nie są obsługiwane. Po kliknięciu „Sign in” użytkownik zmieni stan na zalogowanego i będą dodane jego podstawowe dane. Na razie dane są wpisane ręcznie w kodzie.

Dla zalogowanego użytkownika zmienia się widok strony głównej:

 

Zmieniamy

Obsługę logowania mam w komponencie login-container:

Funkcja loginUser  jest przekazana do komponentu Login i przypięta do przycisku „Sign in”. Znajduje się w niej wysyłanie akcji do Reduxa. Odpowiada za to metoda  dispatch() . Przekazujemy do niej akcję, którą chcemy wykonań. Moje akcje tworzę za pomocą metod, które mam w innym folderze. W tym momencie dla użytkownika mam dwie zdefiniowane akcje:

Typy akcji biorę z kolejnego pliku. Są to po prostu stringi przechowywane w zmiennych.

 

Przechwytywanie akcji

Za obsługę akcji odpowiada reducer. Akcjami użytkownika zajmuje się user-reducer:

Jako parametr podawany jest aktualny stan aplikacji. Jeśli dopiero uruchamiamy aplikację i jeszcze nie ma ona stanu to korzystamy z wartości domyślnych.

Reducer na podstawie typu akcji zmienia stan aplikacji. Metoda  assign()  pozwala utworzyć nowy obiekt na podstawie istniejącego zmieniając tylko część danych. Robię tak ponieważ reducer nie powinien modyfikować przekazywanych do niego obiektów tylko zwracać nowe.

User-reducer odpowiada tylko za stan użytkownika. Dzięki odpowiedniej konfiguracji możemy odseparować od siebie różne reducery:

W przyszłości będę tutaj dodawał kolejne reducery dla kolejnych fragmentów aplikacji.

Oczekiwanie

Na koniec pokażę jak obsługuję zmianę stanu. Np. dla komponentu wyświetlającego widok strony głównej wygląda to tak:

W kodzie używam biblioteki React-redux. Dzięki niej mogę po prostu użyć metody  connect() . Dzięki tej metodzie nasz komponent będzie się zmieniał kiedy zmieni się stan wybranych wartości w aplikacji. Będzie nasłuchiwał zmian stanu. W tym wypadku obchodzi nas informacja czy użytkownik jest zalogowany. Metoda  mapStateToProps()  odpowiada za „przetłumaczenie” wartości trzymanych przez Reduxa na parametry przekazywane do komponentu. Komponent działa tak jakby miał po prostu przekazywane parametry. Nie wie, że odpowiada za nie Redux.

Podsumowanie

Nareszcie zrobiłem coś co działa. Czuję się coraz pewniej w świecie Reacta.

Na pewno popełniam masę błędów dlatego chętnie wysłucham każdej uwagi od osób, które pracują z tą technologią dłużej ;)

Aktualny kod znajdziecie na GitHubie pod adresem:  https://github.com/zajacmarekcom/letswrite. Nie jest on ładny, ale najpierw chcę zrobić coś co działa. Później będę sprzątał.

Niedługo będę musiał zabrać się za najważniejsze funkcje aplikacji :P Zachęcam do śledzenia bloga i zaglądania na fanpage na Facebooku ;)

Ciekawe kiedy zamienię w postach logo konkursu na logo aplikacji…

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *