'React couldn't pass a data from one class component into another using Link

I am trying the pass data to a new page by using Link, in doing so I used the following code.

 <Link
            className="option"
            to={{
              pathname: this.state.pathname,
              state: id
            }}
          >
            <span className="color-primary"> <button style={{ color: "white" }} 
              className="transaction-button"><i className="material-icons" style={{ fontSize: "18px" }}>sync_alt</i> Transaction</button>
            </span>
          </Link>

In the page routed, I tried to handle the data by the following code.

console.log(this.props)

The output is an empty object.

{}

Both pages are class component



Solution 1:[1]

I assume you are using react-router.

In the first page, where you use <Link>...</Link> you're doing the right thing.

At this point there are two alternatives: you can use function or class to create the component.

IF YOU USE A FUNCTION

In the second page, to take the data you passed, you have to import useLocation:

import { useLocation } from 'react-router';

And then, inside the function, you have to call it and extract the state from it:

const location = useLocation();
console.log(location.state);

Inside location.state you have the state you passed from the previous page.

IF YOU USE A CLASS

In this case, things are little more complicated, but you can use withRouter in order to inject location inside your component props.

So, first of all you need to import PropsTypes and withRouter:

import PropTypes from 'prop-types';
import { withRouter } from 'react-router';

Then you have to write your class like this:

class Child extends React.Component {
    static propTypes = {
        location: PropTypes.object.isRequired,
    };

    render() {
        const { location } = this.props;

        console.log(location.state);

        return {
           <div> ... </div>
        };
    }
}
export withRouter(Child);

In this way inside location.state you have the state you passed from the previous page.

Solution 2:[2]

If you are using a class, there is no withRouter any more. What happened to withRouter? I need it!

This question usually stems from the fact that you're using React class components, which don't support hooks. In React Router v6, we fully embraced hooks and use them to share all the router's internal state. But that doesn't mean you can't use the router. Assuming you can actually use hooks (you're on React 16.8+), you just need a wrapper.

So, you'll need to create your own wrapper, as shown in the docs.

Here is my implementation, a little more easy-to-use than doc example:

import React from 'react';
import {useLocation, useNavigate, useParams} from 'react-router-dom';

function withRouter(Component) {
  function ComponentWithRouterProp(props) {
    let location = useLocation();
    let navigate = useNavigate();
    let params = useParams();
    return <Component {...props} {...{location, navigate, params}} />;
  }

  return ComponentWithRouterProp;
}

export default withRouter;

Use (when exporting your component):

export default withRouter(Link);

More Use-cases Example -> for other people that came here:

Example of loading batch of components wrapped with withRouter, or just your Link component.

const routingList = [{title: 'Home', search: '/', component: Home, icon: 'fa-home'},{...}]

<Routes>
    {
      routingList.map((routing) => {
       let Child = routing.component;
       return <Route key={routing.search} path={routing.search} element={<Child {...routing.compProps} />} />;
     })
    }
    <Route path="/link" element={<Link />} />
</Routes>

And, in your component, you can use:

this.props.location.pathname
this.props.params.paramName

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2