'How can I dispatch an action using useEffect in main app.js?

I want to dispatch an action whenever any page or component of my app loads. So what I am trying to do is to dispatch the action using store.dispatch inside useEffect hook in main App.js file.

When I try, it gives a Maximum update depth exceeded Error

I have seen it done in a tutorial or two, I just cant find what I am doing wrong. Is there any other way of achieving this? Please take a look!

Here is my App.js

import React, { useEffect } from "react";
import { Provider } from "react-redux";
import { BrowserRouter, Route, Routes } from "react-router-dom";

import Login from "./pages/Login";
import Landing from "./pages/Landing";
import Contact from "./pages/Contact";
import Dashboard from "./pages/Dashboard";

import store from "./store";
import { loadUser } from "./tasks/authT";
import setAuthToken from "./utils/setAuthToken";
import PrivateRoutes from "./utils/PrivateRoutes";

if (localStorage.token) {
  setAuthToken(localStorage.token);
}

const App = () => {
  useEffect(() => {
    store.dispatch(loadUser());
  }, []);
  return (
    // <Landing />
    <Provider store={store}>
      <BrowserRouter>
        <Routes>
          <Route exact path="/" element={<Landing />} />
          <Route exact path="/contact" element={<Contact />} />
          <Route exact path="/login" element={<Login />} />
          <Route
            exact
            path="/dashboard"
            element={
              <PrivateRoutes>
                <Dashboard />
              </PrivateRoutes>
            }
          />
        </Routes>
      </BrowserRouter>
    </Provider>
  );
};

export default App;

this is the action I am trying to dispatch

export const loadUser = () => async (dispatch) => {
  if (localStorage.token) {
    setAuthToken(localStorage.token);
  }
  try {
    const res = await axios.get("/api/auth");
    dispatch({
      type: USER_LOADED,
      payload: res.data,
    });
  } catch (error) {
    dispatch({
      type: AUTH_ERROR,
    });
  }
};


Solution 1:[1]

Try to use hook useDispatch from react-redux. Also wrap your App.js in <Provider store={store}> .

index.js

<Provider store={store}>
     <App />
</Provider>

App.js

import { useDispatch } from 'react-redux';
const App = () => {
     const dispatch = useDispatch();
     ...
     useEffect(() => {
         loadUser()(dispatch);
     }, []);
     ...

}

Solution 2:[2]

That error occurs because:

if (localStorage.token) {
    setAuthToken(localStorage.token);
}

that cause a component render, so useEffect triggers and dispatch loadUser().

useEffect(() => {
    store.dispatch(loadUser());
}, []);

it triggers because the dependency array is empty. I suggest to add authToken as a dependency in the array.

useEffect(() => {
    store.dispatch(loadUser());
}, [authToken]);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Andronicus