0

I have my routes defined and my links working fine. I would like to pass a prop through the link when the component is called by the router. I dont know if that is even possible.

For better understanding please check in the code: // I WANT TO PASS THE CURRENT PROJECT AS A PROP HERE and //I WANT TO GET THE PASSED PROP IN THE LINK HERE

My functional component in react:

const ProjectList = () => {
....//not meaningful code. I get my data from a call to a database so its not passed in as an argument

return(
    <div className="project-list section">
      { projects && projects.map( project => {
        const path = '/project/' + project.id;
        return (
          <Link to={path} key={project.id}> // I WANT TO PASS THE CURRENT PROJECT AS A PROP HERE
            <ProjectSummary project={project} deleteCallback={projectDelete}/>
          </Link>
        )
      })}  
    </div>
  )
}

My routes setup (imports omitted):

function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <NavBar />
        <Switch>
          <Route exact path='/' component={Dashboard}/>
          <Route
          path='/project/:id'
          render={(props) => (
            <ProjectDetails {...props}/> //I WANT TO GET THE PASSED PROP IN THE LINK HERE
          )}
          />
          <Route path='/signin' component={SignIn}/>
          <Route path='/signup' component={SignUp}/>
          <Route path='/create' component={CreateProject}/>
        </Switch>
      </div>
    </BrowserRouter>
  );
}

export default App;

This is to get the property from a functional component, called when the user clicks the link so called by the Router. This is where I would pass the prop in, on the Router call.

Not very relevant, but to check the name of the according Route child component from the code above, it would be a:

const ProjectDetails = (project: IFirebaseProject) => {
    //....not meaningfull code
}

I checked approximations as:

<Link to="ideas" params={{ testvalue: "hello" }}>Create Idea</Link>

or:

<Link to={{
  pathname: '/tylermcginnis',
  state: {
    fromNotifications: true
  }
}}>Tyler McGinnis</Link>

This last one is very similar to what I would like to do, this is pass a state or an object with properties through, however I am not able to make it work.

Other attempts got from here

Relevant versions info from the package.json:

"typescript": "^4.1.3",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-redux": "^7.2.2",
"react-router-dom": "^5.2.0",
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
rustyBucketBay
  • 4,320
  • 3
  • 17
  • 47
  • Are you just asking how to access the `id` value from the route's `match.params` object? Or how to pass additional route state to the receiving component? – Drew Reese Feb 21 '21 at 22:58
  • How to pass a prop from the link component to the receiving component. I am aware I can access the id. Thanks – rustyBucketBay Feb 21 '21 at 23:00
  • So, your last version using route state then. What isn't working as expected? – Drew Reese Feb 21 '21 at 23:01
  • The question is how can I pass an object (the projectList object) from the `ProjectList ` component, through the `Link` component to the `ProjectDetails` component. So that when the `ProjectDetails` is opened, I have the info available – rustyBucketBay Feb 21 '21 at 23:05
  • It is not a matter of whether it works or not, the question is how can I achieve that – rustyBucketBay Feb 21 '21 at 23:06
  • can that be done using the route state? or can be new props mapped to that route state you mention? thanks – rustyBucketBay Feb 21 '21 at 23:09
  • That's exactly what route state is for, sending additional data with the route transition to the receiving route. – Drew Reese Feb 21 '21 at 23:12

2 Answers2

2

If I understand your question correctly, you want to pass additional route state to the Route rendering the component, but you don't want to rework the component being rendered to read anything from route props.

You can "sip" the passed route state to be injected/passed as the named prop your component consumes.

<Link
  to={{
    pathname: path,
    state: {
      project,
    },
  }}
  key={project.id}
>
  <ProjectSummary project={project} deleteCallback={projectDelete}/>
</Link>

Destructure the passed route state value to be passed as specific named prop.

<Route
  path='/project/:id'
  render={({ location }) => {
    const { state } = location;
    return <ProjectDetails project={state.project} /> 
  }}
/>
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • thanks a lot for your answer. I am almost there, I am having a problem with the location type `Object is of type 'unknown'.ts(2571)`. Any `import` missing to type this up? I need to type the state as the location is of type `Location` – rustyBucketBay Feb 21 '21 at 23:21
  • It seems impossible to match the types, so any comment on that regard will be much appreciated. However what you answered is exectly what I wanted to do. Thanks a lot – rustyBucketBay Feb 22 '21 at 01:58
1

Your last idea should work with passing the state according to react router documentation, maybe you looking for props in component props, but the link state value will be in router location object, location = useLocation(), https://reactrouter.com/web/api/location

Luke Celitan
  • 322
  • 1
  • 11
  • thanks for your answer. I know that I got the chance of accessing the location. With that I can get my Id of interest and look for my component info in the database. But my doubt is if I can avoid that workaround and pass props in the link directly from where the component is called. That way I would not have to rework the component info, as it would be passed in the link as a prop... – rustyBucketBay Feb 21 '21 at 22:50
  • [here](https://stackoverflow.com/questions/30115324/pass-props-in-link-react-router) there is a clear example of what I want to do, but I cannot get it to work – rustyBucketBay Feb 21 '21 at 22:52