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.

Advertisement

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

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement