skip to Main Content
import { useState, useEffect } from "react";
import { useJwt } from "react-jwt";
import { useDispatch, useSelector } from "react-redux";
import {useNavigate} from "react-router-dom"

import { setUserData, clearUserData } from "./features/auth/authSlice";
import { getAccount } from "./features/user/dataSlice";

import Header from "./components/Header";
import Announcement from "./components/Announcement";
import Sidebar from "./components/Sidebar";
import Navbar from "./components/Navbar";
import Loader from "./components/Loader";

import Home from "./pages/HomePage";
import FundAccount from "./pages/FundAccount";
import Withdraw from "./pages/Withdraw";
import BuyData from "./pages/BuyData";
import BuyAirtime from "./pages/BuyAirtime";
import PayCableTv from "./pages/PayCableTv";
import PayElectricity from "./pages/PayElectricity";
import Profile from "./pages/Profile";
import Setting from "./pages/Setting";
import Transactions from "./pages/Transactions";

const BASE_URL =
  import.meta.env.VITE_MODE === "DEV"
    ? import.meta.env.VITE_BASE_URL_TEST
    : import.meta.env.VITE_BASE_URL_LIVE;

function Dashboard({currentPage, setCurrentPage}) {
  const [isMenuOpen, setIsMenuOpen] = useState(false);
  const [showMenu, setShowMenu] = useState(false);
  
  const [isLoading, setIsLoading] = useState(false);
  const [active, setActive] = useState(false);
  const [isTransActive, setIsTransActive] = useState(false);
  const [urlState, setUrlState] = useState("#dashboard")

  const navigate = useNavigate()

  const toggleMenu = () => setIsMenuOpen((prevState) => !prevState);

  const closeAllMenu = () => {
    showMenu === true ? setShowMenu(false) : null;
    if (active) {
      setActive(false);
    }
    if (isTransActive) {
      setIsTransActive(false);
    }
  };

  const handleLogout = () => {
    localStorage.removeItem("user");
    localStorage.removeItem("account");
    dispatch(clearUserData());
    window.location = `${BASE_URL}/users/logout`;
  };

  
  const showPage = (pageTitle) => {
    const url = window.location.pathname;
    let newState = url;

    const fragments = [
      "#dashboard",
      "#fund-account",
      "#withdraw",
      "#transactions",
      "#buy-data",
      "#buy-airtime",
      "#pay-electricity-bill",
      "#pay-cable-tv",
      "#profile",
      "#setting",
    ];

    // const currentFragment = window.location.href.split("#")[1]

    // console.log(currentFragment)
    // console.log(pageTitle);
    // console.log(url);

    switch (pageTitle) {
      case "Home":
        newState += "#dashboard";
        //window.history.replaceState(null, "", newState);
        
        return (
          <Home
            setCurrentPage={setCurrentPage}
            setIsLoading={setIsLoading}
            isTransActive={isTransActive}
            setIsTransActive={setIsTransActive}
          />
        );
      case "Fund Account":
        newState += "#fund-account";
        
        // window.history.replaceState(null, "", newState);
        return <FundAccount setIsLoading={setIsLoading} />;
      case "Withdraw":
        newState += "#withdraw";
        
        // window.history.replaceState(null, "", newState);
        return <Withdraw setIsLoading={setIsLoading} />;
      case "Transactions":
        newState += "#transactions";
        
        // window.history.replaceState(null, "", newState);
        return <Transactions setIsLoading={setIsLoading} />;
      case "Buy Data":
        newState += "#buy-data";
        
        // window.history.replaceState(null, "", newState);
        return <BuyData setIsLoading={setIsLoading} />;
      case "Buy Airtime":
        newState += "#buy-airtime";
        
        // window.history.replaceState(null, "", newState);
        return <BuyAirtime setIsLoading={setIsLoading} />;
      case "Pay Electricity Bill":
        newState += "#pay-electricity";
        
        // window.history.replaceState(null, "", newState);
        return <PayElectricity setIsLoading={setIsLoading} />;
      case "Pay Cable Tv":
        newState += "#pay-cable-tv";
        
        // window.history.replaceState(null, "", newState);
        return <PayCableTv setIsLoading={setIsLoading} />;
      case "Profile":
        newState += "#profile";
        
        // window.history.replaceState(null, "", newState);
        return <Profile setIsLoading={setIsLoading} />;
      case "Setting":
        newState += "#setting";
        
        // window.history.replaceState(null, "", newState);
        return <Setting setIsLoading={setIsLoading} />;
      default:
        newState += "#dashboard";
        
        // window.history.replaceState(null, "", newState);
        return <Home setIsLoading={setIsLoading} />;
    }
  };

  const dispatch = useDispatch();

  const { user } = useSelector((state) => state.auth);
  const { isDataLoading } = useSelector((state) => state.data);
  const { isPurchaseLoading } = useSelector((state) => state.purchase);

  const account = JSON.parse(localStorage.getItem("account"));

  const urlParams = new URLSearchParams(window.location.search);
  const token = urlParams.get("token");
  const getToken = token && useJwt(token);

  useEffect(() => {
    if (token && getToken && !getToken?.isExpired && !user) {
      localStorage.setItem("user", JSON.stringify(getToken.decodedToken));
      dispatch(setUserData(getToken.decodedToken));
    }
  }, [getToken?.decodedToken, dispatch]);

  useEffect(() => {
    if (user) dispatch(getAccount(user.id));
  }, [user, dispatch]);

  useEffect(() => {
    const uri = new URL(`${window.location.protocol}//${window.location.host}`)
  }, [])
  

  return (
    <>
      {isDataLoading && <Loader />}
      {isLoading && <Loader />}
      {isPurchaseLoading && <Loader />}
      <div
        className={`layout-wrapper layout-content-navbar ${
          isMenuOpen ? "layout-menu-expanded" : ""
        }`}
        onClick={(e) => closeAllMenu(e)}
      >
        <div className="layout-container">
          <Sidebar
            currentPage={currentPage}
            setCurrentPage={setCurrentPage}
            setIsMenuOpen={setIsMenuOpen}
            handleLogout={handleLogout}
          />
          {/* <!-- Layout container --> */}
          <div className="layout-page">
            <Navbar
              isMenuOpen={isMenuOpen}
              setIsMenuOpen={setIsMenuOpen}
              handleClick={toggleMenu}
              setCurrentPage={setCurrentPage}
              showMenu={showMenu}
              setShowMenu={setShowMenu}
              handleLogout={handleLogout}
            />
            {/* <!-- Content wrapper --> */}
            <div className="content-wrapper">
              {/* <!-- Content --> */}
              <div className="container-xxl flex-grow-1 container-p-y">
                {currentPage === "Profile" ||
                currentPage === "Setting" ||
                currentPage === "Transactions" ? (
                  ""
                ) : (
                  <div className="row">
                    <Header
                      account={account}
                      setCurrentPage={setCurrentPage}
                      active={active}
                      setActive={setActive}
                    />
                    <Announcement />
                  </div>
                )}

                {showPage(currentPage)}
              </div>
              <footer className="content-footer footer bg-footer-theme">
                <div className="container-xxl d-flex flex-wrap justify-content-between py-2 flex-md-row flex-column">
                  
                </div>
              </footer>
              <div className="content-backdrop fade"></div>
            </div>
            {/* <!-- Content wrapper --> */}
          </div>
          {/* <!-- / Layout page --> */}
        </div>

        {/* <!-- Overlay --> */}
        <div
          className="layout-overlay layout-menu-toggle"
          onClick={() => setIsMenuOpen(false)}
        ></div>
      </div>
    </>
  );
}

export default Dashboard;

I am trying to create a react application which vite where I send data from a backend with a different url (http://localhost:3500). I make a redirect from the backend to the vite frontend and send the data through a query param called token then I use the useJWT to decode the token and make I dispatch, my problem is that I want to change the page url from localhost:5173?token=… to localhost:5173#dashboard but when I use the window.location.pushState(null, "", newState) or replaceState(null, "", newState), I get the error below

Warning: React has detected a change in the order of Hooks called by Dashboard. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks

Previous render Next render

  1. useContext useContext

  2. useContext useContext

  3. useRef useRef

  4. useCallback useCallback

  5. useRef useRef

  6. useMemo useMemo

  7. useSyncExternalStore useSyncExternalStore

  8. useEffect useEffect

  9. useDebugValue useDebugValue

  10. useDebugValue useDebugValue

  11. useContext useContext

  12. useRef useRef

  13. useCallback useCallback

  14. useRef useRef

  15. useMemo useMemo

  16. useSyncExternalStore useSyncExternalStore

  17. useEffect useEffect

  18. useDebugValue useDebugValue

  19. useDebugValue useDebugValue

  20. useContext useContext

  21. useRef useRef

  22. useCallback useCallback

  23. useRef useRef

  24. useMemo useMemo

  25. useSyncExternalStore useSyncExternalStore

  26. useEffect useEffect

  27. useDebugValue useDebugValue

  28. useDebugValue useDebugValue

  29. useState useEffect
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    at Dashboard (http://localhost:5173/src/Dashboard.jsx?t=1692559813161:41:20)
    at App
    at Provider (http://localhost:5173/node_modules/.vite/deps/react-redux.js?v=cb62aef7:1507:3)

if there is anyone who understands hooks or have a better way I can send data from a different url to this vite url without having to cause this problem should please help me out with the solution. Thanks

I tried moving the useEffect way above all my code, but it still tells me about the problem and I also found out that the error occurs whenever there is a useEffect and window.history.pushState in One Component
And I a thinking of changing the whole code to use react-router-dom

2

Answers


  1. Your problem lies in

    Dashboard

    component.

    Basically, you have some conditional hooks (etc: hooks inside if statements) and this is bad, at least for react.

    Login or Signup to reply.
  2. the problem is with this line:

    const getToken = token && useJwt(token)
    

    there is a conditional usage of a hook (the hook is executed only when token is thruthy)

    Instead, try passing token into useJwt in all cases, e.g.:

    const getToken = useJwt(token)
    

    or, if you need to handle undefined tokens, you could do something like this.

    const getToken = useJwt(token || '')
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search