Trying to use redux and save user data in local storage but caught problem

Viewed 164

I was trying after any user registered or login into this website user will be confirmed in the server and the response will be stored in local storage. Based on the user I will check in the local storage is user available and then login into the site. It works fine when users newly register and get a server response it saves local storage and the user Navigates to the Profile. But after I check the same user to login form I got a response from the server but it is not going saved in local storage so I can not able to check the user in local storage and it did not navigate the profile section.

** here's my App js file **


function App() {
  const user = useSelector((state) => state.authReducer.authData);
  console.log(user);
  return (
    <div className="App">
      <div className="blur" style={{ top: "-18%", right: 0 }}></div>
      <div className="blur" style={{ top: "36%", left: "-8rem" }}></div>

      <Routes>
        <Route
          path="/"
          element={user ? <Navigate to="home" /> : <Navigate to="auth" />}
        />
        <Route
          path="/home"
          element={user ? <Home /> : <Navigate to="../auth" />}
        />

        <Route
          path="/auth"
          element={user ? <Navigate to="../home" /> : <Auth />}
        />
      </Routes>
    </div>

auth Reducer file

  state = { authData: null, loading: false, error: false },
  action
) => {
  switch (action.type) {
    case "AUTH_START":
      return { ...state, loading: true, error: false };

    case "AUTH_SUCCESS":
      localStorage.setItem("profile", JSON.stringify({ ...action?.data }));
      return { ...state, authData: action.data, loading: false, error: false };
    case "AUTH_FAIL":
      return { ...state, loading: false, error: true };
    default:
      return state;
  }
};

export default authReducer;

**Index.js file **


import authReducer from "./AuthReducer";

export const reducers = combineReducers({authReducer}) 

**Redux store file **

  legacy_createStore as createStore,
  applyMiddleware,
  compose,
} from "redux";
import thunk from "redux-thunk";
import { reducers } from "../Reducer";

function saveToLocalStorage(store) {
  try {
    const serializedStore = JSON.stringify(store);
    window.localStorage.setItem("store", serializedStore);
  } catch (e) {
    console.log(e);
  }
}

function loadFromLocalStorage() {
  try {
    const serializedStore = window.localStorage.getItem("store");
    if (serializedStore === null) return undefined;
    return JSON.parse(serializedStore);
  } catch (e) {
    console.log(e);
    return undefined;
  }
}
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const persistedState = loadFromLocalStorage();

const store = createStore(
  reducers,
  persistedState,

  composeEnhancers(applyMiddleware(thunk))
);

store.subscribe(() => saveToLocalStorage(store.getState()));

export default store;

And finally, I got an error in my console log that is

  • Actions must be plain objects. Instead, the actual type was: 'Promise'. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions *
2 Answers

Check your App.jsx component located on src/pages/Auth/Auth.jsx. Fix your login import syntax like this.

import { signUp, logIn } from "../../Action/AuthAction";

To store redux data in localStorate or sessionStorage try to use redux-persist

Wrap your App.js with PersistGate from redux-persist

and then in store file instead of create a function saveToLocalStorage define a rootConfig where storage comes from redux-persist

const rootPersistConfig = {
  key: 'root',
  storage,
};

if you want to store data in sessionStorage

const rootPersistConfig = {
  key: 'root',
  storage: sessionStorage,
};

use it as

const persistedReducer = persistReducer(rootPersistConfig, authReducer);

now use persistedReducer as reducers in your index.js file.

// if you want to combine multiple reducer then you can do this like

const rootReducer = combineReducers({
  user: userReducer,
  cart: persistReducer(cartPersistConfig, cartReducer),
});

and then make a persistedReducer like this insted of authReducer you'll put your combined rootReducer

const persistedReducer = persistReducer(rootPersistConfig, rootReducer);

for more details check redux-persist

Related