1

I am getting this error but the problem is I am not understanding where I am getting this error. Because I didn't use pathname as variable. And it is also showing that above error occurring in Router component But I imported it from react-rotuer-dom.

[Click here for the description of the error] (https://i.stack.imgur.com/tKPKK.png).

index.js:

import React from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import "react-toastify/dist/ReactToastify.css";
import App from "./App";
import { Provider } from "react-redux";
import { configureStore } from "@reduxjs/toolkit";
import allReducers from "./reducers/allreducers";
import thunk from "redux-thunk";
import { getEducations } from "./actions/educationAction";
import { getExperiences } from "./actions/experienceAction";
import { getprojects } from "./actions/projectAction";
import { getSkills } from "./actions/skillAction";
import api from "./apis/serverApi";

const store = configureStore({
  reducer: allReducers,
  middleware: [thunk],
  devTools: process.env.NODE_ENV !== "production",
});

store.dispatch(getEducations());
store.dispatch(getExperiences());
store.dispatch(getprojects());
store.dispatch(getSkills());

const user = JSON.parse(localStorage.getItem("userData"));

if (user !== null) {
  api.defaults.headers.common["Authorization"] = `Bearer ${user.token}`;
}

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

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

App.js:

import React, { useState, useEffect } from "react";
import { Router, Route, Routes } from "react-router-dom";
import { useSelector } from "react-redux";
import PortfolioUI from "./pages/PortfolioUI";
import Login from "./components/User/Login/Login";
import SideBar from "./components/Admin/SideBar/SideBar";
import EducationAdmin from "./pages/EducationAdmin";
import { ToastContainer } from "react-toastify";
import history from "./shared/history";
import SecureRoute from "./shared/SecureRoute";
import ExperienceAdmin from "./pages/ExperienceAdmin";
import SkillAdmin from "./pages/SkillAdmin";
import MessageAdmin from "./pages/MessageAdmin";
import isLogin from "./shared/authorization";
import ProjectAdmin from "./pages/ProjectAdmin";
import NotFound from "./pages/NotFound";

function App() {
  const [isLogged, setIsLogged] = useState(isLogin);
  const login = useSelector((state) => state.login.isLogin);

  useEffect(() => {
    setIsLogged(isLogin);
  }, [login]);

  return (
    <div className="App">
      <Router history={history}>
        {isLogged && <SideBar />}
        <Routes>
          <Route path="/login" exact component={Login} />
          <SecureRoute path="/education" exact component={EducationAdmin} />
          <SecureRoute path="/experience" exact component={ExperienceAdmin} />
          <SecureRoute path="/project" exact component={ProjectAdmin} />
          <SecureRoute path="/skill" exact component={SkillAdmin} />
          <SecureRoute path="/messages" exact component={MessageAdmin} />
          <Route path="/" exact component={PortfolioUI} />
          <Route path="*" component={NotFound} />
        </Routes>
      </Router>
      <ToastContainer
        position="top-right"
        autoClose={1000}
        hideProgressBar={false}
        newestOnTop={false}
        closeOnClick
        rtl={false}
        pauseOnFocusLoss
        draggable
        pauseOnHover
      />
    </div>
  );
}

export default App;

secureRouter.js:

import React, { useState } from "react";
import { Route, useNavigate } from "react-router-dom";
import isLogin from "./authorization";

const SecureRoute = (props) => {
  const [isLogged] = useState(isLogin);
  const navigate = useNavigate();

  if (!isLogged) {
    navigate("/", { state: { from: props.location }, replace: true });
    return null; // or a loading indicator, etc.
  }

  return <Route path={props.path} element={<props.component {...props} />} />;
};

export default SecureRoute;

serverApi.js:

import axios from "axios";

const api = axios.create({
  baseURL: "http://localhost:8080",
});

export const setAuthorizationToken = (token) => {
  if (token) {
    axios.defaults.headers.common["Authorization"] = `Bearer ${token}`;
  } else {
    delete axios.defaults.headers.common["Authorization"];
  }
};

export default api;

export const domainName = "http://localhost:8080/";

educationApi.js:

import api from "./serverApi";

export const addEducationApi = (education) => {
  return api.post("/educations/", education);
};

export const getEducationsApi = () => {
  return api.get("/educations/");
};

export const deleteEducationApi = (educationId) => {
  return api.delete(`/educations/${educationId}`);
};

export const updateEducationApi = (educationId, education) => {
  return api.put(`/educations/${educationId}`, education);
};

experienceApi.js:

import api from "./serverApi";

export const addExperienceApi = (experience) => {
  return api.post("/experiences/", experience);
};

export const getExperiencesApi = () => {
  return api.get("/experiences/");
};

export const deleteExperienceApi = (experienceId) => {
  return api.delete(`/experiences/${experienceId}`);
};

export const updateExperienceApi = (experienceId, experience) => {
  return api.put(`/experiences/${experienceId}`, experience);
};

messageApi.js:

import api from "./serverApi";

export const getMessagesApi = () => {
  return api.get("/messages/", {
    headers: {
      Authorization: `Bearer ${
        JSON.parse(localStorage.getItem("userData")).token
      }`,
    },
  });
};

export const updateMessageApi = (messageId, message) => {
  return api.put(`/messages/${messageId}`, message);
};

projectApi.js:

import api from "./serverApi";

export const addProjectApi = (project) => {
  return api.post("/projects/", project);
};

export const getProjectsApi = () => {
  return api.get("/projects/");
};

export const deleteProjectApi = (projectId) => {
  return api.delete(`/projects/${projectId}`);
};

export const updateProjectApi = (projectId, project) => {
  return api.put(`/projects/${projectId}`, project);
};

skillApi.js:

import api from "./serverApi";

export const addSkillApi = (skill) => {
  return api.post("/skills/", skill);
};

export const getSkillsApi = () => {
  return api.get("/skills/");
};

export const deleteSkillApi = (skillId) => {
  return api.delete(`/skills/${skillId}`);
};

export const updateSkillApi = (skillId, skill) => {
  return api.put(`/skills/${skillId}`, skill);
};

userApi.js:

import api from "./serverApi";

export const loginApi = (authData) => {
  return api.post("/users/login", authData);
};

history.js:

import { createBrowserHistory } from "history";

const history = createBrowserHistory();

export default history;

If you need any other file for finding the error than please ask for that. I can't find the error so I need yours help . So if anyone can solve the error it you will be a lot for me. As a beginner I got stack here. So if anyone can help me out it will be highly appreciated.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • Seems like the problem occurs because of "history". Because history returns pathnames. Check your `import history from "./shared/history";` or share this file content here so we can check it too. – GLHF May 20 '23 at 09:57
  • Sure. I already added. Kindly help me, thanks in advance –  May 20 '23 at 10:01
  • Have you tried the solutions in this question? https://stackoverflow.com/questions/43620289/react-router-cannot-read-property-pathname-of-undefined – GLHF May 20 '23 at 10:04
  • Can you give the example that which solution and where I should use it? Actually I am not understanding . If you give an example it would be better for me to understand –  May 20 '23 at 10:09
  • have you tried logging your `history` ? try logging it and let me know what it displays. – sarfaraj shah May 20 '23 at 10:24
  • It is showing a object ``` –  May 20 '23 at 12:31
  • sharfaraj shah , Image link: https://imgtr.ee/i/2VujL –  May 20 '23 at 12:39

1 Answers1

0

Your code appears to be partially upgraded from react-router-dom@4/5 to react-router-dom@6. The RRDv6 Router component you are using is missing a couple required props, location and navigator.

See Router:

declare function Router(
  props: RouterProps
): React.ReactElement | null;

interface RouterProps {
  basename?: string;
  children?: React.ReactNode;
  location: Partial<Location> | string; // <-- required!
  navigationType?: NavigationType;
  navigator: Navigator;                 // <-- required!
  static?: boolean;
}

pathname can't be destructured from an undefined location object.

https://github.com/remix-run/react-router/blob/main/packages/react-router/lib/components.tsx#L354

let {
  pathname = "/", // <-- can't access property of undefined!
  search = "",
  hash = "",
  state = null,
  key = "default",
} = locationProp;

The code you are using is passing a history prop, but as you can see, this isn't a prop the RRDv6 Router component consumes.

Since I don't see any other place in your code where the custom history object is used or referenced, you should just import and use the BrowserRouter. All the high-level RRDv6 routers instantiate the history reference internally.

...
import { BrowserRouter, Route, Routes } from "react-router-dom";
...

function App() {
  ...

  return (
    <div className="App">
      <BrowserRouter>
        ...
      </BrowserRouter>
      ...
    </div>
  );
}

export default App;

If your code does actually need an external history reference, then you should import and use the HistoryRouter.

...
import {
  unstable_HistoryRouter as HistoryRouter,
  Route,
  Routes
} from "react-router-dom";
...
import history from "./shared/history";
...

function App() {
  ...

  return (
    <div className="App">
      <HistoryRouter history={history}>
        ...
      </HistoryRouter>
      ...
    </div>
  );
}

export default App;

Now that the Router situation should be sorted out, there's an issue with the routes themselves. react-router-dom@6 Routes component takes only Route and React.Fragment as valid children. The SecureRoute doesn't work as the route component any longer, it must be converted to a layout route component. It conditionally renders an Outlet for nested routes to be rendered into, or a redirect to any non-protected route.

Example:

import React, { useState } from "react";
import { Outlet, Navigate, useLocation } from "react-router-dom";

const SecureRoute = () => {
  const location = useLocation();
  const isLoggedIn = useSelector((state) => state.login.isLogin);

  if (isLoggedIn === undefined) {
    return null; // or a loading indicator, etc.
  }

  return isLoggedIn
    ? <Outlet />
    : <Navigate to="/login" state={{ from: location }} replace />;
};

export default SecureRoute;

All the routes should render their content on the single available element prop as a ReactNode, e.g. as JSX. component, and render and children function props are older RRDv4/5 props and were removed in v6.

...

function App() {
  const isLoggedIn = useSelector((state) => state.login.isLogin);

  return (
    <div className="App">
      <BrowserRouter>
        {isLogged && <SideBar />}
        <Routes>
          <Route path="/login" element={<Login />} />
          <Route element={<SecureRoute />}>
            <Route path="/education" element={<EducationAdmin />} />
            <Route path="/experience" element={<ExperienceAdmin />} />
            <Route path="/project" element={<ProjectAdmin />} />
            <Route path="/skill" element={<SkillAdmin />} />
            <Route path="/messages" element={<MessageAdmin />} />
          </Route>
          <Route path="/" element={<PortfolioUI />} />
          <Route path="*" element={<NotFound />} />
        </Routes>
      </BrowserRouter>
      ...
    </div>
  );
}

export default App;
Drew Reese
  • 165,259
  • 14
  • 153
  • 181