Skip to content
Advertisement

Passing props to dynamically rendered components in React

I have a page that is displaying several of my star components that each have their own name and a prop called starType I am generating several different of these stars with the following code

if (num > 0) {
        return (
          <div className="starWrapper">
            <Star
              name={`${makeid()}`}
            
              starType={`${starList[Math.floor(Math.random() * 6 + 1)]} ${posList[Math.floor(Math.random() * 9 + 1)]}`}
            ></Star>
           
           {makeStars((num - 1))}
          </div>
          
        );

And this is the star component

 <NavLink to={props.name}>
      <h1 className="star-label">{props.name}</h1>
      <div className={``}>
        <div className={`starBall ${props.starType}`}></div>
      </div>
    </NavLink>

At the moment I want the user to be able to click on each star and have it lead to a page. I have achieved that with react-router’s dynamic routing

  <Route
          exact
          path="/:id"
          render={(props) => <GenerateSystem {...props} />}
        />

the issue is I want the page that is generated from my generateSystem component to have the starType prop passed to it by the star component. I am aware of React’s one way data flow and I think that might be the issue. How can I pass prop data from an auto generated component to another auto generated component?

My full code is viewable here. The components I’m talking about are in the interstellar-view and systems folder.

Answer

since you are passing name through URL params so passing starType using query params is an easy option.

So URL would look like this www.example.com/123?starType=red-giant

In your star.jsx, make a modification like this

<NavLink to={`/${props.name}?starType=${props.starType}`}>
 ...
</NavLink>

In your App.js, make a modification like this

<Switch >
    <Route exact path="/:id"  component={GenerateSystem} />
    <Route exact path="/sol" component={SolSystem} />
    <Route exact path="/" component={Interstellar} />
</Switch>

(We do not need to render and pass props since we can use useParams in GenerateSystem.js)

In your GenerateSystem.js, make a modification like this

import React from "react";
import { Link, useLocation, useParams } from "react-router-dom";

function useQuery() {
  return new URLSearchParams(useLocation().search);
}

export const GenerateSystem = (props) => {
    const {name} = useParams();
    const query = useQuery();
    const starType = query.get('starType')

    return(<div className={starType}>System <p>{name}</p></div>)
}

Refs:

https://reactrouter.com/web/api/Hooks/useparams

https://reactrouter.com/web/example/query-parameters

EDIT:

You can use Redux-store/Context-API to have a global store, so that name and starType can be stored globally and can be accessed in different components

Advertisement