2016-01-15 20 views
15

Mam 3 pytania ogólne dotyczące Redux i izomorficzna aplikacji:Gdzie ustawić plik cookie w aplikacji Isomorphic Redux?

  • Jaki jest najlepszy sposób na dzielenie się „wykonania” danych między klientem a serwerem? Na przykład, gdy użytkownik zalogował się w odległym interfejsie API, przechowuję obiekt sesji w plikach cookie. W ten sposób, następnym razem klient zażąda mojego front-end, serwer front-end może odczytać pliki cookie i zainicjować sklep redux z jego poprzedniej sesji. Minusem tego jest to, że klient ma do sprawdzenia/unieważnienia sesji podczas rozruchu (np. W componentDidMount komponentu root). Czy powinienem poprosić o stronę serwera sesji, a nie czytać z plików cookie?
  • Gdzie powinienem wykonać operację przechowywania plików cookie, w twórcach akcji lub w reduktorach? Czy powinienem przechowywać plik cookie w moim reduktorze, który obsługuje sesję użytkownika?
  • Gdzie powinienem wykonać operację przekierowania użytkownika (przez router reagujący)? Znaczy kiedy mój użytkownik jest zalogowany pomyślnie, skąd mam wysyłką działania przekierowania (z loginActionCreator raz obietnica logowania jest rozwiązany ?, gdzie indziej?)

Z góry dzięki.

Odpowiedz

4

Pytanie 2: należy wykonać przechowywanie plików cookie w swoim kreatorze akcji. Reduktory muszą pozostać czystymi funkcjami.

Naprawdę przykro mi, że nie znam odpowiedzi na 1 & 3, ale mam nadzieję, że to pomoże!

+0

Dziękuję za odpowiedź. Czy masz link, który wyjaśnia, dlaczego? – Cnode

+1

Myślę, że to dlatego, że reduktory muszą pozostać synchroniczne. Nie mogę znaleźć oryginalnego posta, który przeczytałem na ten temat, ale to dotyczy: https://github.com/rackt/redux/issues/291 –

2

Powinieneś prawdopodobnie podzielić pytania na trzy różne pytania związane z przepełnieniem stosu, ponieważ wszystkie one są trochę inne.

Zgadzam się z Ethanem, twoje reduktory powinny być czyste bez żadnych skutków ubocznych. W każdym razie to jest cel (znany także jako najlepsza praktyka). Jednak Ben Nadel bada pytania pod tym kątem i sugeruje stworzenie warstwy workflow do zarządzania logiką biznesową zamiast obciążania sklepu. Powinieneś zapoznać się z jego artykułem Managing Locally Cached Data with Redux in AngularJS, aby uzyskać więcej informacji na ten temat.

+0

Dziękuję za odpowiedź. Przeczytałem link Ethana Clarka i było to bardzo interesujące. Usunąłem wszystkie efekty uboczne z moich reduktorów i umieściłem je w moich twórcach akcji. Przeczytam twój artykuł i podzielę moje pytania na 3 pytania przepełnienia stosu. – Cnode

6

Udało mi się uzyskać naprawdę zgrabną strukturę aplikacji. Oto co znalazłem na każde pytania:

  • I tylko mój udział między klientem a serwerem frontonu tokena serwer API za pomocą plików cookie. Za każdym razem, gdy klient żąda witryny. Serwer frontowy wywołuje serwer API w celu sprawdzenia poprawności sesji. Jeśli te serwery są w tej samej sieci, jest naprawdę szybki (< 5 ms). Ponadto wstępnie wstępne renderowanie niektórych przydatnych danych dla klienta na serwerze. Udaje mi się załadować i załadować moją aplikację (ładowanie javascript) na klienta w ciągu 600ms. Jest całkiem przyzwoity.

  • Akcja przechowywania cookie jest w moich twórcach akcji. Jak powiedział Ethan Clark, musimy utrzymywać reduktory w czystości. O wiele łatwiej jest testować.

  • Nadal wysyłam przekierowanie do mojego twórcy logowania po uwierzytelnieniu użytkownika. Wydaje mi się, że łatwiej jest przetestować niż wysłać akcję po rozwiązaniu obietnicy w komponencie lub w innym miejscu.

W rzeczywistości, mając to na uwadze, możemy sprawić, że aplikacja będzie naprawdę łatwa do przetestowania (należy oczekiwać, że twórca czynności będzie musiał mieć tonę szpiegów).

Mam nadzieję, że komuś pomoże.

Dzięki za udział.

+1

Czy masz repozytorium GitHub lub jakiś przykład tego? –

+1

Wszelkie przykłady kodu byłyby bardzo mile widziane! – user1828780

+0

@Cnode udało Ci się rozwiązać? Jakiś przykładowy kod? – souravb

0

Pliki cookie są zsynchronizowane - możesz albo uwodnić i zasubskrybować swój sklep, albo zrobić reduktor meta, który owija się wokół reduktora, zanim zostanie dodany do createStore. Oto krótki przykład poniżej:

//first option 
const Cookie = require('js-cookie'); 
const loadState = (key) => Cookie.getJSON(key); 
const saveState = (nextState, key) => Cookie.set(key, nextState); 
const persistedState = loadState('todos'); 
const store = createStore(
    todoApp, 
    persistedState 
); 

store.subscribe(throttle(() => { 
    saveState({ 
    todos: store.getState().todos, 
    }, 'todos'); 
}, 1000)); 

//second option - meta reducer 
// usage 
    const Cookie = require('js-cookie'); 

    export function cookieMeta (
     key: string, 
     reducer: any, 
     expiry: Date | number = 365, 
     path: string = '/', 
     domain: string = window.location.hostname): Function { 
     return function(state: any, action: any): any { 
     let nextState = reducer(state, action); 
     let cookieState = Cookie.getJSON(key); 

     if (action.type.includes('DELETE')) { 
      Cookie.remove(key); 
     } else if (!nextState && cookieState || action.type === '@@redux/INIT') { 
      nextState = cookieState; 
     } else if (nextState && nextState !== cookieState) { 
      Cookie.set(key, nextState, { expires: expiry, path: path, domain: domain, secure: process.env.local }); 
     } 
     return nextState; 
     }; 
    }; 
// how to implement the meta reducer 
import { todos } from './todos'; 
import { cookieMeta } from './middleware/cookieMeta'; 
export function TODOS_REDUCER (state: any, action: any) { 
    return cookieMeta('todos', todos)(state, action); 
} 
export const todoApp = combineReducers({ todos: TODOS_REDUCER })