Quero persistir algumas partes da minha árvore de estado no localStorage. Qual é o local apropriado para fazer isso? Redutor ou ação?
fonte
Quero persistir algumas partes da minha árvore de estado no localStorage. Qual é o local apropriado para fazer isso? Redutor ou ação?
O redutor nunca é um local apropriado para fazer isso, porque os redutores devem ser puros e sem efeitos colaterais.
Eu recomendaria fazer isso em um assinante:
store.subscribe(() => {
// persist your state
})
Antes de criar a loja, leia as partes persistentes:
const persistedState = // ...
const store = createStore(reducer, persistedState)
Se você usar, combineReducers()
notará que os redutores que não receberam o estado serão "inicializados" normalmente usando o state
valor padrão do argumento. Isso pode ser bastante útil.
É recomendável que você renuncie ao seu assinante para não gravar muito rapidamente no localStorage, ou você terá problemas de desempenho.
Finalmente, você pode criar um middleware que o encapsule como alternativa, mas eu começaria com um assinante porque é uma solução mais simples e faz o trabalho bem.
Para preencher os espaços em branco da resposta de Dan Abramov, você pode usar o
store.subscribe()
seguinte:Antes de criar a loja, verifique
localStorage
e analise qualquer JSON sob sua chave da seguinte maneira:Você passa essa
persistedState
constante para o seucreateStore
método assim:fonte
persistedState
retornar eminitialState
vez de um objeto vazio? Caso contrário, acho quecreateStore
será inicializado com esse objeto vazio.Em uma palavra: middleware.
Confira redux-persist . Ou escreva o seu.
[ATUALIZAÇÃO 18 de dezembro de 2016] Editado para remover a menção de dois projetos semelhantes agora inativos ou descontinuados.
fonte
Se alguém tiver algum problema com as soluções acima, você pode escrever para si mesmo. Deixe-me mostrar o que eu fiz. Ignore as
saga middleware
coisas, apenas se concentre em duas coisaslocalStorageMiddleware
ereHydrateStore
métodos. alocalStorageMiddleware
puxar todos osredux state
e coloca-olocal storage
erehydrateStore
puxar todos osapplicationState
no armazenamento local se presente e coloca-lo emredux store
fonte
localStorage
mesmo quando nada na loja mudou? Como compensar as gravações desnecessáriasNão consigo responder @Gardezi, mas uma opção baseada em seu código poderia ser:
a diferença é que estamos apenas salvando algumas ações. Você pode usar uma função de debounce para salvar apenas a última interação do seu estado
fonte
Estou um pouco atrasado, mas implementei um estado persistente de acordo com os exemplos declarados aqui. Se você deseja atualizar o estado apenas a cada X segundos, essa abordagem pode ajudá-lo:
Definir uma função de wrapper
Chame uma função de invólucro no seu assinante
Neste exemplo, o estado é atualizado no máximo a cada 5 segundos, independentemente da frequência com que uma atualização é acionada.
fonte
(state) => { updateLocalStorage(store.getState()) }
emlodash.throttle
como este:store.subscribe(throttle(() => {(state) => { updateLocalStorage(store.getState())} }
e remover tempo verificando dentro da lógica.Com base nas excelentes sugestões e trechos de código curto fornecidos em outras respostas (e no artigo Médio de Jam Creencia ), aqui está uma solução completa!
Precisamos de um arquivo contendo 2 funções que salvem / carreguem o estado para / do armazenamento local:
Essas funções são importadas pelo store.js, onde configuramos nossa loja:
NOTA: Você precisará adicionar uma dependência:
npm install lodash.throttle
A loja é importada para o index.js, para que possa ser transmitida ao provedor que envolve o App.js :
Observe que as importações absolutas exigem essa alteração no YourProjectFolder / jsconfig.json - indica onde procurar arquivos, se não os encontrar primeiro. Caso contrário, você verá reclamações sobre a tentativa de importar algo de fora do src .
fonte