Zaczynam używać Facebook React w projekcie Backbone i na razie wszystko idzie naprawdę dobrze.
Zauważyłem jednak, że do mojego kodu React wkradło się pewne duplikowanie.
Na przykład mam kilka widżetów przypominających formularze ze stanami takimi jak INITIAL
, SENDING
i SENT
. Po naciśnięciu przycisku formularz musi zostać zweryfikowany, zostanie wysłane żądanie, a następnie stan zostanie zaktualizowany. Stan jest this.state
oczywiście przechowywany w React wraz z wartościami pól.
Gdyby to były widoki Backbone, wyodrębniłbym klasę bazową o nazwie, FormView
ale mam wrażenie, że React nie wspiera ani nie obsługuje podklas w celu udostępnienia logiki widoku (popraw mnie, jeśli się mylę).
Widziałem dwa podejścia do ponownego wykorzystania kodu w Reakcie:
- Mixiny (takie jak LinkedStateMixin, który jest dostarczany z React);
- Komponenty kontenera (takie jak reakcja-nieskończone przewijanie ).
Czy mam rację, że mixiny i kontenery są preferowane zamiast dziedziczenia w Reakcie? Czy to przemyślana decyzja projektowa? Czy bardziej sensowne byłoby użycie komponentu mixin lub kontenera dla mojego przykładu „widżetu formularza” z drugiego akapitu?
Oto istota z FeedbackWidget
i JoinWidget
w ich aktualnym stanie . Mają podobną strukturę, podobną beginSend
metodę i oba będą wymagały wsparcia walidacji (jeszcze nie ma).
źródło
Odpowiedzi:
Na początku próbowałem użyć do tego podkomponentów i wyodrębnić
FormWidget
iInputWidget
. Jednak porzuciłem to podejście w połowie, ponieważ chciałem mieć lepszą kontrolę nad generowanymiinput
i ich stanem.Dwa artykuły, które najbardziej mi pomogły:
Okazało się, że wystarczyło napisać dwa (różne) miksy:
ValidationMixin
iFormMixin
.Oto jak je rozdzieliłem.
ValidationMixin
Mixin walidacji dodaje wygodne metody do uruchamiania funkcji walidatora na niektórych właściwościach stanu i przechowuje właściwości „błędne” w
state.errors
tablicy, dzięki czemu można podświetlić odpowiednie pola.Źródło ( treść )
Stosowanie
ValidationMixin
ma trzy metody:validate
,hasError
iresetError
.Oczekuje, że klasa zdefiniuje
validators
obiekt, podobnie jakpropTypes
:Gdy użytkownik naciska przycisk przesyłania, dzwonię
validate
. Wywołanievalidate
spowoduje uruchomienie każdego walidatora i wypełnieniethis.state.errors
tablicą zawierającą klucze właściwości, które nie przeszły weryfikacji.W mojej
render
metodzie używamhasError
do generowania poprawnej klasy CSS dla pól. Kiedy użytkownik umieszcza fokus wewnątrz pola, wzywam,resetError
aby usunąć podświetlenie błędu do następnegovalidate
wywołania.FormMixin
Forma mixin obsługuje stan formularza (edytowalny, przesyłający, przesłany). Możesz go użyć do wyłączenia wejść i przycisków podczas wysyłania żądania i odpowiednio zaktualizować widok, gdy zostanie wysłany.
Źródło ( treść )
Stosowanie
Oczekuje, że komponent zapewni jedną metodę:
sendRequest
:, która powinna zwrócić obietnicę Bluebird. (Zmodyfikowanie go do pracy z Q lub inną biblioteką obietnic jest trywialne).Zapewnia wygodę metod, takich jak
isFormEditable
,isFormSubmitting
iisFormSubmitted
. Zapewnia on również sposobu skopać żądanie:submitForm
. Możesz to wywołać z programuonClick
obsługi przycisków formularza .źródło
FormInput
rozmawiam ze swoim właścicielem przezformLink
.formLink
jest jakvalueLink
, i jest zawracany zFormMixin
„slinkValidatedState(name, validator)
metody.FormInput
pobiera swoją wartość zformLink.value
i wywołujeformLink.requestBlur
iformLink.requestFocus
- powodują walidację wFormMixin
. Na koniec, aby dostosować rzeczywisty komponent używany do wprowadzania danych, mogę przekazać goFormInput
:<FormInput component={React.DOM.textarea} ... />
done
do bluebirda, a kod będzie działał jak w Q (lub natywne obietnice) - oczywiście bluebird jest lepszy. Zauważ również, że składnia zmieniła się w Reakcie od czasu odpowiedzi.Tworzę SPA z Reactem (w produkcji od 1 roku) i prawie nigdy nie używam mixinów.
Jedyny przypadek, jaki mam obecnie w przypadku mixinów, to udostępnianie zachowań wykorzystujących metody cyklu życia Reacta (
componentDidMount
itp.). Ten problem został rozwiązany przez komponenty wyższego rzędu, o których Dan Abramov mówi w swoim łączu (lub za pomocą dziedziczenia klasy ES6).Miksery są również często używane w frameworkach, aby udostępnić API frameworka wszystkim komponentom, używając "ukrytego" kontekstu Reacta. Nie będzie to już potrzebne w przypadku dziedziczenia klas ES6.
W większości innych przypadków, miksy są używane, ale tak naprawdę nie są potrzebne i można je łatwiej zastąpić prostymi pomocnikami.
Na przykład:
Możesz bardzo łatwo refaktoryzować
LinkedStateMixin
kod, tak aby składnia wyglądała następująco:Czy jest jakaś duża różnica?
źródło