2015-11-06 8 views
16

o ile rozumiem Redux, chodzi o utrzymanie całego stanu interfejsu w jednym sklepie (aby móc łatwo odtworzyć pewne stany i nie mieć żadnych skutków ubocznych). Możesz manipulować stanem poprzez wyzwalanie akcji, które wyzwalają reduktory.Jak przekazywać zmiany stanu interfejsu użytkownika między komponentami React a Redux?

Obecnie piszę małą aplikację podobną do bloga, w której można po prostu tworzyć i edytować posty. Mam okno tworzenia post, z grubsza metoda składnika Apprender zwraca coś takiego:

<div> 
    <AppBar ... /> 
    <PostFormDialog 
     addPost={actions.addPost} 
     ref="postFormDialog" /> 
    <PostList 
     posts={posts} 
     actions={actions} /> 
</div> 

Moje pytanie brzmi: czy stan okna (otwarte lub zamknięte) będzie częścią obiektu państwowej składnika aplikacji? A zatem powinno otwierania i zamykania okna dialogowego być wywołane poprzez działania zamiast robić coś jak następuje:

onTriggerCreatePostDialog(e) { 
    this.refs.postFormDialog.show(); 
} 

gdzie onTriggerCreatePostDialog jest wyzwalany poprzez kliknięcie jakiegoś słuchacza na przycisk „Utwórz” lub tak.

Wydaje mi się to trochę dziwne, zrobić to poprzez działania, ponieważ wprowadza rodzaj "pośrednictwa".

Jednak zakładając, że chcę ponownie użyć okna dialogowego do akcji edycji, muszę mieć możliwość otwarcia okna dialogowego z elementów, które znajdują się głębiej w strukturze komponentu, na przykład ze składnika Post, który jest elementem potomnym modelu PostList składnik. Co mogę zrobić, to przekazać funkcję onTriggerCreatePostDialog dół hierarchii poprzez właściwość props, ale wydaje mi się kłopotliwe ...

Więc int koniec jest również o komunikacji między komponentami, które nie znajdują się w bezpośrednim rodzic-dziecko związek. Czy są inne opcje? Czy powinienem jakoś wykorzystać globalną magistralę zdarzeń? Jestem obecnie dość niepewny.

Odpowiedz

2

Stan okna dialogowego powinien znajdować się w sklepie redux, wywołanym przez akcje. to, czy powinno być renderowane, powinno być określone przez sprawdzenie tego stanu w sklepie redux.

App.render() powinno być coś takiego:

render() { 
    const { showDialog } = this.props; 

    return (
    <div> 
     <AppBar ... /> 
     { showDialog ? <PostFormDialog ... /> : false } 
     <PostList ... /> 
    </div> 
); 
} 

gdzie mapStateToProps byłoby coś state => {{ showDialog: state.showDialog }}

chodzi o dostarczanie twórcy działania, przekazując ją w dół drzewa rekwizyty to prawdopodobnie poprawny sposób to zrobić chyba że masz dobrą lokalizację, gdzie ma sens mieć inny inteligentny komponent.

+0

Załóżmy, że okno dialogowe nie jest modalne. Początkowo nie jest pokazywana, a jej stan jest zarządzany tak, jak proponujesz. Klikam przycisk, 'showDialog' staje się prawdą i pojawia się to okno dialogowe. Teraz, jeśli kliknę gdzieś indziej niż okno dialogowe, zostanie ono ponownie zamknięte, ale 'showDialog' nie zostanie odpowiednio zmanipulowane, chyba że wyraźnie zajmuję się tym przypadkiem w' PostFormDialog'. To tylko jeden przykład, w którym obsługa stanu okna staje się uciążliwa, moim zdaniem. Czy mimo to zrobiłbyś to tak? –

+0

Jeśli chodzi o inteligentny komponent: czy na przykład rozsądne byłoby wprowadzenie innego inteligentnego komponentu do zarządzania stanem modalnego okna dialogowego? Zakładając, że dialog może być użyty do stworzenia nowego postu i edycji istniejących. Ponadto musisz obsłużyć takie rzeczy jak "czyszczenie" okna dialogowego po pomyślnym utworzeniu/edycji itd. –

+0

to podejście będzie działać, ale będzie również łamać wszelkie animacje wyglądu/znikania dialogów, prawda? Ponieważ element nadrzędny został ponownie renderowany, okno dialogowe zostanie natychmiast usunięte z ekranu. Zastanawiam się, jakie jest najlepsze rozwiązanie tego problemu? –

7

Wydaje mi się, że jesteś na dobrej drodze. Dokumenty na początku mogą być nieco trudne, ale mogę powiedzieć, w jaki sposób mój zespół i ja używamy implementacji.

Aby odpowiedzieć na twoje pierwsze pytanie; jeśli stan jest specyficzny dla komponentu, to zachowujemy ten stan z komponentem. Przykładem może być panel, który strony zapisują lokalnie --- nic innego nie musi być świadome tego zachowania. Tak więc w tym przypadku nie wywoływalibyśmy działania redux po zmianie strony, która byłaby obsługiwana wewnętrznie w strukturze komponentu przy użyciu refs.

Nasz stan redux składa się głównie z danych zebranych za pośrednictwem żądań xhr lub ze stanu wspólnego. Przykładem stanu współdzielonego byłoby zarządzanie zakresem czasowym pomiędzy wieloma komponentami, które używają tego zakresu do wyświetlania danych.W tym przypadku uruchomimy działanie redux; zaktualizuj stan daty o wszystko, co zostało zmienione (przy jednoczesnym uaktualnieniu niektórych innych elementów stanu za pośrednictwem xhr), a następnie ostatecznie wróci do składników i ponownie renderowania.

Po tym, działania wyzwalające za pomocą instrukcji są całkowicie dopuszczalne, chodzi tylko o konkretny przypadek użycia.

Aby odpowiedzieć na twoje drugie pytanie; redux zaleca stosowanie koncepcji komponentu Smart & Dumb. Więc masz rację, że przekazałeś funkcję w dół drzewa, aby wykorzystać głupie komponenty.

Używamy mapDispatchToProps w naszej konfiguracji connect. W zasadzie przekazuje się funkcję, która zwraca obiekt funkcji "dyspozytorzy". Będziesz mieć dostęp do tych funkcji bezpośrednio w swoim komponencie inteligentnym this.props.

Przykład mapDispatchToProps

function mapDispatchToProps(dispatch) { 
    return { 
    myAction:() => dispatch(actions.myAction()), 
    }; 
} 

tak, że pracuje 99% czasu, ale Zabrakło mi w niektórych przypadkach rogu, gdzie używamy globalnego autobusu zdarzenia, więc nie bój się do wykorzystania zarówno podczas próby przywiązania do metody komponentu Smart/Dumb tak bardzo, jak to możliwe.

Na marginesie, polecam użyć reselect, aby zmapować stan redux do inteligentnego komponentu. Możesz także znaleźć inne świetne zasoby reduxa here (jest kilka rzeczy, których używamy).

+1

Co na temat uruchamiania akcji Redux dla komponentów siostrzanych? Powiedzmy, że chcesz mieć jedną akcję Redux w systemie siostrzanym A, która aktualizuje sklep, który ma zostać potwierdzony, i wyzwala dostęp do rekwizytów w połączeniu z siostrzanym B. Czy po prostu łączyłbyś się z komponentem nadrzędnym, który ma rodzeństwo A i B jako dzieci? Dzięki! –

Powiązane problemy