LocalStorage with Redux

I was trying to make add-to-cart functionality but every time i refresh the site, cart data was gone, so I first implemented a small part/project in my stackblitz and then I tried to put the same thing in my site that i was building with typescript. Here is the self-explanatory code.

Just a key terminology that you should be aware of

  • 1 react js
  • 2 redux
  • 3 redux toolkit and related key terms
  • 4 redux thunk - read the theory
  • 5 redux middleware - redux theory
  • 6 we do not use side Effects in redux reducers

code -

index.js

import React, { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { Provider } from 'react-redux';
import store from './redux/store';
import App from './App';

const rootElement = document.getElementById('root');
const root = createRoot(rootElement);

root.render(
  <StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </StrictMode>
);

storej.js

import { createSlice, configureStore } from '@reduxjs/toolkit';

const initialAuthState = {
  isAuthenticated: false,
};

const authSlice = createSlice({
  name: 'auth',
  initialState: initialAuthState,
  reducers: {
    login(state) {
      state.isAuthenticated = true;
    },
    logout(state) {
      state.isAuthenticated = false;
    },
  },
});

const localStorageMiddleware = ({ getState }) => {
  return (next) => (action) => {
    const result = next(action);
    localStorage.setItem('applicationState', JSON.stringify(getState()));
    return result;
  };
};

const reHydrateStore = () => {
  if (localStorage.getItem('applicationState') !== null) {
    return JSON.parse(localStorage.getItem('applicationState'));
  }
};

const store = configureStore({
  reducer: {
    auth: authSlice.reducer,
  },
  preloadedState: reHydrateStore(),
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(localStorageMiddleware),
});

export const authActions = authSlice.actions;

export default store;

App.js

import React from 'react';
import './style.css';
import { useSelector, useDispatch } from 'react-redux';
import { authActions } from './redux/store';

export default function App() {
  const dispatch = useDispatch();
  const { isAuthenticated } = useSelector((state) => state.auth);
  console.log(isAuthenticated);
  console.log(authActions);
  return (
    <div>
      <span>{isAuthenticated.toString()}</span>
      <h4>Authentication with ReduxToolkit with localStorage</h4>
      {!isAuthenticated && (
        <button onClick={() => dispatch(authActions.login())}>Login</button>
      )}
      {isAuthenticated && (
        <button onClick={() => dispatch(authActions.logout())}>Logout</button>
      )}
    </div>
  );
}

you should keep slices and store them separately because you may have thousands of slices in your project storing them separate will make the code shorter for one file.

use this code

{ getState }: { getState: () => any }

in typescript or you may get the error.

https://www.typescriptlang.org/docs/handbook/2/functions.html https://reactjs.org/ https://redux.js.org/introduction/getting-startedText

here is the working code -> %[stackblitz.com/edit/react-js5nnl?file=src%2..