web-dev-qa-db-fra.com

Pouvez-vous ou devez-vous utiliser localStorage dans l'état initial de Redux?

Par exemple...

export const user = (state = {
  id: localStorage.getItem('id'),
  name: localStorage.getItem('name'),
  loggedInAt: null
}, action) => {
    case types.LOGIN:
      localStorage.setItem('name', action.payload.user.name);
      localStorage.setItem('id', action.payload.user.id);
      return { ...state, ...action.payload.user }

    default:
      return {  ...state, loggedInAt: Date.now() }
}

C'est une version réduite de ce que je fais, par défaut renvoie l'état de localStorage comme prévu. Cependant, l'état de ma demande est en fait vide une fois que j'ai actualisé la page.

24
Ewan Valentine

Redux createStore Le 2ème paramètre est destiné à l'initialisation du magasin:

createStore(reducer, [initialState], [enhancer])

Vous pouvez donc faire quelque chose comme ceci:

const initialState = {
  id: localStorage.getItem('id'),
  name: localStorage.getItem('name'),
  loggedInAt: null
};

const store = createStore(mainReducer, initialState);

Étant donné que les réducteurs doivent être des fonctions pures (c'est-à-dire sans effets secondaires) et localStorage.setItem est un effet secondaire, vous devez éviter d'enregistrer dans localStorage dans un réducteur.

Au lieu de cela, vous pouvez:

store.subscribe(() => {
    const { id, name } = store.getState();

    localStorage.setItem('name', name);
    localStorage.setItem('id', id);
});

Cela se produit chaque fois que l'état change, ce qui peut affecter les performances.

Une autre option consiste à enregistrer l'état uniquement lorsque la page est fermée (actualisation du nombre) à l'aide de onBeforeUnload:

window.onbeforeunload = () => {
    const { id, name } = store.getState();

    localStorage.setItem('name', name);
    localStorage.setItem('id', id);
};
39
Ori Drori