Where to Write to Localstorage in a Redux App

Where to write to localStorage in a Redux app?

Reducer is never an appropriate place to do this because reducers should be pure and have no side effects.

I would recommend just doing it in a subscriber:

store.subscribe(() => {
// persist your state
})

Before creating the store, read those persisted parts:

const persistedState = // ...
const store = createStore(reducer, persistedState)

If you use combineReducers() you’ll notice that reducers that haven’t received the state will “boot up” as normal using their default state argument value. This can be pretty handy.

It is advisable that you debounce your subscriber so you don’t write to localStorage too fast, or you’ll have performance problems.

Finally, you can create a middleware that encapsulates that as an alternative, but I’d start with a subscriber because it’s a simpler solution and does the job well.

Write and then read at the same time from LocalStorage in ReactJS + Redux

In your example you are setting token for your axios when your files load. That means only when the app loads, not after your login. So that item in localStorage is null at that time.

So the solution is to setup interceptor for axios instead of your instance of authAxios:

const App = (props) => {

// This will trigger when only once when page refreshes
useEffect(() => {
axios.interceptors.request.use(
(config) => {
config.headers = {
...config.headers,
Authorization: `Token ${token ? localStorage.getItem("token") : null}`
};

return config;
},
(error) => {
props.dispatchRedirectToLoginPage()
return Promise.reject(error);
}
);
}, [])

return <div>Your app</div>
}

So that every request executes this function and it will take token from localStorage.

And every api call that you make make it with axios.get(...) or what ever method you need.

LocalStorage with react-redux

I would suggest storing the data in local storage with the following commands.

Set the data in localStorage can be done with the command:

localStorage.setItem('nameForData', variableNameForData);

To retrieve the data when required.

var variableNameForData = localStorage.getItem('nameForData')

To remove the data from localStorage:

localStorage.removeItem('nameForData')

These would typically be put inside action creators with a dispatch to change the state of some Boolean that tracks the applications interaction with localStorage.

For example you might have a state that is set to true when the local storage is created.

On refresh you might call an action creator that checks the local storage exists, and if it does set that boolean back to true or if it does not exist you are back to creating local storage and then set it to true.

You could put this function in componentWillMount(){} and it will be called when the component is first rendered, and thus in the case of a refresh.

Docs for component life cycle and specifically componentWillMount here

Docs for local storage here

How do I store my state in localstorage in my Redux application?

You have to use redux persist

// configureStore.js

import { createStore } from 'redux'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web

import rootReducer from './reducers'

const persistConfig = {
key: 'root',
storage,
}

const persistedReducer = persistReducer(persistConfig, rootReducer)

export default () => {
let store = createStore(persistedReducer)
let persistor = persistStore(store)
return { store, persistor }
}


// App.js

import { PersistGate } from 'redux-persist/integration/react'

// ... normal setup, create store and persistor, import components etc.

const App = () => {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<RootComponent />
</PersistGate>
</Provider>
);
};

Edited check below:
change codesandbox to:

store/index.js:

// store/index.js:
import { createStore } from "redux";
import { persistStore } from "redux-persist";
import rootReducer from "../reducers";

export const store = createStore(rootReducer);

export const persistor = persistStore(store);



*******
reducers/index.js:

// reducers/index.js:
import { combineReducers } from "redux";
import { persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage";
import listReducers from "./listReducers";

const persistConfig = {
key: "root",
storage,
whitelist: ["lists"]
};

export default persistReducer(persistConfig, combineReducers({
lists: listReducers
}));



root project index.js:

// index.js:
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import { store, persistor } from "./store";
import "./styles/main.scss";

import App from "./components/App";
import * as serviceWorker from "./serviceWorker";

ReactDOM.render(
<Provider store={store}>
<PersistGate persistor={persistor}>
<App />
</PersistGate>
</Provider>,
document.getElementById("root")
);

serviceWorker.unregister();


Related Topics



Leave a reply



Submit