1

I have been learning about React Router have run into some issues while I was trying to implement a dynamic page creation based on the slugs that I receive from my fetch api call.

basically, I'm trying to redirect user to a new page after they click on a link - This new page will be a new component and I will make a new api call on this component with the slug as my search parameter.

However I'm struggling to dynamically change pages based on slugs.

Here is the component (BoxScore.js) in which I make the initial fetch and display data -

import React from "react";
import { useEffect, useState } from "react";

import { Link } from "react-router-dom";

const BoxScore = () => {
  const [users, setUsers] = useState([]);
  const [pageNumber, setPageNumber] = useState(1);



  useEffect(() => {
    fetch(
      `myfetchapihere.com`
    )
      .then((response) => {
        return response.json();
      })
      .then((data) => {
        setUsers(data);
        console.log(data);
        setPageNumber(pageNumber);
      });
  }, [pageNumber]);
     return (
         <> {users.map((user) => (
                <div
                  className="column"
                  key={user.id}
                  id={user.id}>
                  <div className="inner">
                    <div className="flex">
                      <h2 className="uk-text-small">
                     
         

 <Link to={user.slug} className="h2 link" id={user.slug}>
    {user.name}
    </Link>
    </div>

    </div></div>
        )}
</>);

In my App.js I have react router set up -

 <Routes>
      <Route path="boxscore/:slug" element={<BoxScore />}>
      <Route path=":slug" element={<OneScore />} />
    </Route>

   </Routes>

My OneScore component which isn't being rendered on the click of the link I set up in the Boxscore component -

import React from 'react'
import BoxScore from './Boxscore'
import { useParams } from "react-router";
import {useEffect} from 'react'

function OneScore() {

    const { slug } = useParams();
    
  useEffect(() => {
    // Fetch post using the postSlug
    console.log({slug});
  }, [slug]);

  return (
    <div>
          Hiii
    </div>
  )
}

export default OneScore

EDIT - I have managed to make the linking work thanks to @DrewReese comments however, the only issue remains now is that after the url is changed to (ex- www.a.com/boxscore/) the 'OneScore' component is not rendered instead the same BoxScore remains just the url is changed.

2 Answers 2

1

Instead of a raw anchor (<a />) tag use the Link or NavLink component. These link components work with the routing context being provided by the router. Using the anchor tag will reload the app, which very likely isn't what you want to occur.

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

...

{users.map((user) => (
  <div
    className="column"
    key={user.id}
    id={user.id}
  >
    <div className="inner">
      <div className="flex">
        <Link to={user.slug} className="h2link" id={user.slug}>
          <h2 className="uk-text-small">{user.name}</h2>
        </Link>
      </div>
    </div>
  </div>
)};

The routed component should use the useParams hook to access the route's slug path param and an useEffect hook to rerun any logic that depends on this slug value.

import { useEffect } from 'react';
import { useParams } from 'react-router-dom';

...

const { slug } = useParams();

useEffect(() => {
  // "make a new api call on this component with the slug as my search parameter"
}, [slug]);
Sign up to request clarification or add additional context in comments.

7 Comments

Hey, I did try this earlier and while it works and my url changes to boxscore(slug) but the new component is not being rendered,The UI stays on the same 'Boxscore' component, I think I'm doing smth wrong in the <Routes> part but not sure exactly what that is
@KentrellJr I suppose it depends on that values being mapped from this users array. Could you provide a more complete and comprehensive code example? The main component rendering the mapped users array, the value of users, and both the BoxScore and OneScore components you are trying to link to?
Hey, I have attached the code for OneScore component in my post, the existing code in which I map over the users is a part of my BoxScore component, My only issues now is that when I click on the Link in the boxscore comp the url changes to something like (www.a.com/boxscore/myexampleslug) but the UI remains in BoxScore component instead of routing to the OneScore, As for the values of the users array - It is working fine as I'm able to fetch and render them in the BoxScore component
@KentrellJr Since BoxScore doesn't appear to use the "slug" it makes more sense to have these as your routes: <Route path="boxscore" element={<BoxScore />}> and <Route path="/boxscore/:slug" element={<OneScore />} /> and ensure the links from BoxScore link correctly to "/boxscore/:slug" paths.
Hey, I think I got it working now, the issue was in the Routes like you suggested, I was closing the <Route path="boxscore" element={<BoxScore />}> after <Route path="/boxscore/:slug" element={<OneScore />} />, Once I fixed that it does render a new page with the slug in url. Thank you so much for your patience and help and really appreciate the tip, I'll keep that in mind always!
|
0

Look into useParams to get the slug from the url. https://v5.reactrouter.com/web/api/Hooks/useparams

4 Comments

I have had a look into that but I'm not sure how to even redirect a user to a new dynamic component on click of that <a>.
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
what do you mean by redirect to a new dynamic component? Do you mean change the browser url and load a new page that is dynamic based on the fetch from the slug url or do you mean load a new dynamic component on the same browser url?
Okay so what I mean is suppose my url is - www.a.com/boxscore on load but when a user clicks one of elements it redirects them to a new page - www.a.com/boxscore/<slug> - This new page should be a new component where I can fetch and render data for this specific slug through my api endpoint, I got the url part working now but my new component where I'm passing {slug} into useParams is not rendering and I stay on the same page.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.