2015-11-30 11 views
21

Ho un'app che utilizza un'API di sincronizzazione per ottenere i suoi dati e richiede di archiviare tutti i dati localmente. Il set di dati stesso è molto grande e io sono riluttante a memorizzarlo in memoria, dal momento che può contenere migliaia di record. Poiché non penso che la struttura dei dati sia rilevante, supponiamo che sto costruendo un client di posta elettronica che deve essere accessibile offline e che voglio che il mio meccanismo di archiviazione sia IndexedDB (che è asincrono).Come integrare Redux con dataset molto grandi e IndexedDB

So che una soluzione semplice sarebbe quella di non avere la struttura dati come parte del mio oggetto di stato e solo di compilare lo stato con i dati richiesti (ad esempio: memorizzare il contenuto di posta elettronica nello stato quando viene attivata l'azione EMAIL_OPEN). Questo è abbastanza semplice, specialmente con redux-thunk.

Tuttavia, ciò vorrebbe dire che ho bisogno di compromettere 2 cose:

  1. I dati utente fa parte non è più dello "stato di applicazione", anche se in verità lo è. Dal momento che il comportamento di sincronizzazione è complesso e rimuoverlo dalla macchina dello stato dell'app danneggerà l'eleganza dei concetti di redux (il modo in cui li capisco)
  2. Mi piace molto l'architettura di redux e vorrei che tutta la mia logica la attraversasse , non solo lo stato di visualizzazione.

Esistono best practice su come utilizzare Redux con proprietà di stato non in memoria? La cosa che trovo più difficile da comprendere è che la redux si basa su API sincrone e quindi non posso sostituire il mio oggetto stato con un oggetto stato asincrono (a meno che non rimuovo completamente il redux e lo sostituisca con il mio, implementazione asincrona e connettore).

Non sono riuscito a trovare una risposta usando Google, ma se ci sono già buone risorse sull'argomento mi piacerebbe essere segnalato anche.

UPDATE: domanda è stato risposto, ma ha voluto dare un espianto meglio di come ho implementato che, nel caso in cui qualcuno si imbatte in esso:

L'idea principale è quella di mantenere gli elenchi di cambiamento di client e server utilizzando semplicemente redux riduttori e utilizzare un connettore per ascoltare questi elenchi di modifiche per aggiornare IDB e anche per aggiornare il server con modifiche client:

  1. Quando il cliente apporta modifiche, utilizzare i riduttori per aggiornare l'elenco di modifiche del client.
  2. Quando il server invia aggiornamenti, utilizzare i riduttori per aggiornare l'elenco di modifiche del server.
  3. Un connettore è in attesa di archiviazione e aggiornamenti stato modifiche IDB. Mantenere anche l'elenco interno degli elementi che sono stati modificati.
  4. Quando si aggiorna il server, utilizzare l'elenco degli elementi modificati per prelevare delta da IDB e inviarlo al server.
  5. Quando si accede ai dati, utilizzare normali azioni per tirare da IDB (ad esempio utilizzando redux-thunk)

L'unica avvertenza di questo approccio è che dal momento che il reale stato viene memorizzato in IDB, così noi perdiamo un po ' del valore di avere un oggetto di stato (e anche più difficile da riavvolgere/stato di avanzamento veloce)

+0

Non ho una risposta chiara per voi perché poco è noto e scritto che memorizza grandi set di dati in stato redux. Vorrei solo consigliarti di provare e guardare se redux e reagire in grado di gestire il carico in memoria. Puoi scrivere uno scenario di test abbastanza semplice e vedere se funziona. Si potrebbe anche voler utilizzare una libreria come 'ImmutableJS' che ottimizza l'archiviazione e la mutazione della memoria di dati efficiente. Spero che questo aiuti in qualche modo. Fammi sapere come è andata. Sono davvero curioso della performance. – JensDebergh

+0

Dal momento che voglio supportare il cellulare, l'impronta digitale della memoria non può essere troppo grande. Su molti dispositivi l'allocazione di memoria per JS è piuttosto piccola, per archiviare enormi quantità di dati è solo una pessima idea. – AriehGlazer

risposta

19

Penso che la tua prima impressione sia corretta. Se (!) Non è possibile memorizzare tutto nel negozio, è necessario memorizzare meno nel negozio.Ma credo di poter rendere questa soluzione molto più efficace:

IndexedDB diventa semplicemente un altro endpoint, proprio come qualsiasi API server che consumi. Quando recuperi i dati dal server, lo inoltrerai a IndexedDB, da cui viene quindi popolato il tuo negozio. Il negozio ottiene solo ciò di cui ha bisogno e lo memorizza nella cache finché non diventa troppo grande o stantio.

In realtà non è diverso da, ad esempio, Facebook consuma la propria API. Non ci sono mai tutti i dati per un utente nel negozio. I riferimenti sono implementati con ID e questi vengono caricati quando richiesto.

È possibile mantenere tutta la logica in modo riduttivo. È sufficiente creare azioni come al solito per le azioni dell'utente e le modifiche ai dati, ottenere i dati necessari e elaborarli. L'interfaccia è ancora completamente definita dai dati dell'utente perché hai sempre le informazioni nel negozio necessarie per OTTENERE il resto quando necessario. È solo un po 'condensato, io. e. si salva solo il numero totale di messaggi o gli ID di una casella di posta finché l'utente non vi si avvicina.

Problemi correlati