I cannot user to direct to another page in react-router

Viewed 43

I am working on an anime project and using react-router first time. My problem is that I cannot redirect the user to another page that has anime details.

This is the main component that has anime images and their titles. When the user clicked the image, it has to direct to the anime details component which I cannot do it.

 <Container>
      <Row>
        {animes.map((data) => (
          <Col key={data.mal_id} sm={4}>
            <Link to="/anime-details/:mal_id">
              <Image
                src={data.images.jpg.large_image_url}
                alt={`This is ${data.title}`}
                style={{ height: "350px" }}
                className="mt-4"
                rounded
              />
            </Link>
            <p
              style={{ fontWeight: "bold", fontSize: "1.15rem" }}
              className="mt-2">
              {data.title}
            </p>
          </Col>
        ))}
      </Row>
    </Container>

This is the router in the index.js

const router = createBrowserRouter([
  {
    path: "/",
    element: <Main />,
    children: [
      {
        path: "anime-details/:mal_id",
        element: <AnimeDetails />,
        loader: async ({ request, params }) => {
          return axios(`/anime-details/${params.mal_id}`, {
            signal: request.signal,
          })
        },
      },
    ],
  },
])

Finally, this is the anime details page

import React from "react"

function AnimeDetails() {
  return <div>Anime Details</div>
}

export default AnimeDetails

Thanks in advance!

2 Answers

Issue

From what I can tell the link target path you are trying to use is a bit malformed.

<Link to="/anime-details/:mal_id">
  ...
</Link>

This is linking to a literal path string "/anime-details/:mal_id" and so when the navigation action is effected the user is navigated to "/anime-details/:mal_id" where the mal_id route path param will have the literal value ":mal_id" instead of an actual id value what was being mapped over.

Solution

Inject the animes array data element's mal_id property into the target path string when mapping.

<Link to={`/anime-details/${data.mal_id}`}>
  ...
</Link>

Example:

<Container>
  <Row>
    {animes.map((data) => (
      <Col key={data.mal_id} sm={4}>
        <Link to={`/anime-details/${data.mal_id}`}>
          <Image
            src={data.images.jpg.large_image_url}
            alt={`This is ${data.title}`}
            style={{ height: "350px" }}
            className="mt-4"
            rounded
          />
        </Link>
        <p
          style={{ fontWeight: "bold", fontSize: "1.15rem" }}
          className="mt-2">
          {data.title}
        </p>
      </Col>
    ))}
  </Row>
</Container>

Edit i-cannot-user-to-direct-to-another-page-in-react-router

in my opinion you better to use react-router-dom to navigate some page.

import {useNavigate} from 'react-router-dom';

function Navbar () {
  const navigate = useNavigate();
  
  
  function toDetailAnime(){
  navigate('/DetailAnime')
  }
  
  return (
  <div className="navbar">
      <h1>Anime</h1>
      <ul>
        <li className="navbar-item">
        <a href="/DetailAnime" onClick={toDetailAnime}>
          Detail Anime 
        </a>
        </li>
        <li className="navbar-item">
        <a href="/DetailAnime1" onClick={toDetailAnime1}>
          Pokemon
        </a>
        </li>
)
}

export default Navbar;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Related