Passing data through <Link /> but getting undefined using React Router in React

Viewed 1509

I'm struggling to pass some data from one component to another one using <Link />. I cannot pass any params to my URL so, please excuse that solution. Below are my sample files from my problem,

App.jsx

<BrowserRouter>
  <Router history={history}>
    <Route exact path={'/my-dashboard/first-page'} component={FirstComponent}/>
  </Router>
</BrowserRouter>

LinkingComponent.jsx

const LinkingComponent = ({ data }) => {
  return (
    <Link
      to={{
        pathname: '/my-dashboard/first-page',
        state: { userDetails: data }
      }}
    >
      {data.firstName}
      &nbsp;
      {data.lastName}
    </Link>
  );
};

FirstComponent.jsx

const FirstComponent = props => {
  const {
    location: {
      state: { userDetails }
    }
  } = props;
  console.log('user-detail', userDetails);
 ....
 some data manipulations
 ....
}

Here, the FirstComponent is not directly linked or related to the LinkingComponent. I'm using the LinkingComponent in my dashboard and I am passing my 'data' there. It is receiving it properly in the LinkingComponent. But somehow whenever I try to access it in my FirstComponent, it gives me an error that it is undefined. I have already tried various solutions and read various articles, but couldn't find an appropriate solution.

Please help me with the solution here. TIA.

2 Answers
  1. First, get rid of Router or BrowserRouter, because Router is usually just an alias for BrowserRouter. Below is the import you might see:
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";

And then, your App.jsx will be like:

<Router>
   <Route exact path={'/my-dashboard/first-page'} component={FirstComponent}/>
</Router>
  1. Second, this is seriously wrong:
const FirstComponent = props => {
  const {
    location: {
      state: { userDetails }
    }
  } = props;
  console.log('user-detail', userDetails); // <- Seriously wrong!
  return <div>FirstComponent</div>;
}

Although FirstComponent is a function, it's not a normal javascript function but React functional component! You need to have a life circle method (componentDidMount) to see the userDetails prop.

Assuming that you know Hooks, your FirstComponent will be like:

import { useEffect } from "react"

const FirstComponent = props => {
  const {
    location: {
      state: { userDetails }
    }
  } = props;

  useEffect(() => {
     console.log({ userDetails }); // <- Better console.log with Object
  }, []) // <- empty dependency = componentDidMount

  return <div>FirstComponent</div>;
}
  1. Also, you need to wrap your FirstComponent by withRouter HOC, which is provided by react-router, to get the location prop in your FirstComponent's props.

Here I've created a small example. Play with it.

Related