skip to Main Content

I have a page with localhost:3000/content URL which is having multiple projects in it and each project is associated with a project id. When I click on any project, it use the project id via useParams hook and pass it to the App.js to generate the dynamic route with localhost:3000/content/${ProjectId}. Under every project I have few blogs. To create blogs, I am using the localhost:3000/createblog URL with query search parameter for project. So the actual like that will be used to create the blog is something like localhost:3000/createblog?ProjectId=xxxxxx.

From the createblog page, if I want to go back, using navigate(-1) I am able to go easily. But if I want to use navigate(/content/${projectId}), then its not working. In the console.log I can see the proper value and the same URL worked only once when actually came from /content page to /content/projectId page. The projectId is a string value.

Few code snips for the reference:

  • All the available routes in App.js
<BrowserRouter>
  <Routes>
    <Route exact path="/" element={<HomePage />} />
    <Route path="/login" element={<LoginComponent />} />
    <Route path="/forgot-password" element={<ForgetPasswordComponent />} />
    <Route path="/signup" element={<CreateAccountComponent />} />
        
    <Route
      path="/dashboard"
      element={
        <RequireAuth>
          <LandingPage />
        </RequireAuth>
      }
    />
    
    <Route
      path="/content"
      element={
        <RequireAuth>
          <ContentPage />
        </RequireAuth>
      }
    />
    
    <Route
      path="/content/:projectId"
      element={
        <RequireAuth>
          <ProjectPage />
        </RequireAuth>
      }
    />

    <Route
      path="/createblog"
      element={
        <RequireAuth>
          <CreateBlog />
        </RequireAuth>
      }
    />
    
    <Route path="*" element={<ErrorPage />} />
  </Routes>
</BrowserRouter>
  • ContentPage.jsx
{projects.map((sname) => {
  return (
    <div key={sname.projectKeyId}>
      <Link
        to={sname.projectKeyId}
        state={sname.projectTypeName}
        style={{ textDecoration: "none", color: "#546e7a" }}
      >
        <DataTreeView
          treeItems={projects}
          skId={sname.projectKeyId}
        />
      </Link>
    </div>
  );
})}
  • ProjectPage.jsx
import React, { useEffect, useState } from "react";
import { useLocation, useSearchParams } from "react-router-dom";


const ProjectPage = () => {
  const { projectId } = useParams();
  const [pagesname, setPagesname] = useState([]);
  const [dashboarderror, setDashboarderror] = useState();
  const location = useLocation();
  const [searchParams, setSearchParams] = useSearchParams();
  const pageId = searchParams.get("pageId");

  useEffect(() => {
    async function fetchData() {
      try {
        const authconfig = {
          headers: {
            "Content-Type": "application/json",
            Authorization:
              "Bearer " + JSON.parse(localStorage.getItem("user_token")).token,
          },
        };
        const res = await axios.get(
          dashboardURL,
          authconfig
        );
        for (let i = 0; i < res.data.matrixDetails[2].projects.length; i++) {
          if (
            res.data.matrixDetails[2].projects[i].projectTypeName ===
            location.state
          ) {
            setPagesname(res.data.matrixDetails[2].projects[i].pages);
            );
          }
        }
      } catch (e) {
        setDashboarderror(e);
      }
    }
    fetchData();
  }, [location.state]);

  return (
  <Box>
   {pagesname.map((sname) => {
     return (
       <div key={sname.pageKeyId}>
         <Button
           style={{
            textTransform: "none",
            color: "#546e7a",
            backgroundColor: "transparent",
            padding: "2px",
          }}
          onClick={() =>
            setSearchParams({ pageId: sname.pageKeyId })
          }
        >
          <DataTreeView
            treeItems={pagesname}
            pgCode={sname.pageKeyId}
          />
        </Button>
      </div>
     {pageId && <PageView pageId={pageId} />}
    </Box>
    );
  })}

    )
}

In createblog page, if I will click the cancel button, it should go to the previous page. Here is the code to handle the Cancel button:

const handleClick = () => {
    // navigate(-1);                    // this logic is Working
    navigate(`/content/${projectId}`);  // this logic is not working
  };

and I am calling the same click function in below button code:

<Button
  variant="outlined"
  color="error"
  size="medium"
  onClick={() => handleClick()}
  sx={{
    borderRadius: 10,
    textTransform: "none",
    ":hover": {
      bgcolor: "error",
      color: "error",
      border: "error",
     },
    }}
  >
    Cancel
</Button>

The similar issue is happening when I am displaying the blog as well. The blog display code URL is like localhost:3000/content/projectId?pageId=xxxxxx. I can display all the pages properly. But if due to some reason the page is getting refreshed, when the URL is in localhost:3000/content/projectId?pageId=xxxxxx position, then the page is completely blank but if I will come back to localhost:3000/content/projectId page and refresh, everything working as expected.

2

Answers


  1. Chosen as BEST ANSWER

    Routes were correct. Its the wrong projectName validation condition which was causing the if condition to fail and then it was unable to fetch the pages in that project.

    After some debugging, I found that my condition was wrong. After a page url change, the location.state was changing which was breaking the if condition.

    Old code in ProjectPage.jsx
    for (let i = 0; i < res.data.matrixDetails[2].projects.length; i++) {
      if (
        res.data.matrixDetails[2].projects[i].projectTypeName ===
        location.state
      ) {
        setPagesname(res.data.matrixDetails[2].projects[i].pages);
        );
      }
    }
    

    When the page was loading for the first time, I used to save a localStorage property proName. Hence just get that to validate and it started working.

    New Code in ProjectPage.jsx

    for (let i = 0; i < res.data.matrixDetails[2].projects.length; i++) {
      const spName = JSON.parse(localStorage.getItem("proName"));
      if (
        res.data.matrixDetails[2].projects[i].projectTypeName ===
        location.state || proName === res.data.matrixDetails[2].projects[i].projectTypeName
      ) {
        setPagesname(res.data.matrixDetails[2].projects[i].pages);
        );
      }
    }
    

  2. The first Route in your sample code above has an exact prop. If you were using react-router@5, then the problem could be related to having the following routes in order:

    <Route path="/content" element={<RequireAuth><ContentPage /></RequireAuth>} />
    <Route path="/content/:projectId" element={<RequireAuth><ProjectPage /></RequireAuth>} />
    

    You wouldn’t be able to reach the second one without having exact on the first one.

    If you are using react-router@6, I don’t think there is enough information in the question to help. I’m not sure exactly where you are getting projectId from in the CreateBlog component. Here is a working StackBlitz which I think has all the functionality you have described above:
    https://stackblitz.com/edit/stackblitz-starters-skfc4l?file=src%2FApp.js

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search