React Router DOM can't read location state

Viewed 3705

I've seen this question before but only applied to Class components so I am not sure how to apply the same approach for functional components.

It's simple, I have a link <Link to={{ pathname="/first-page" state: { name: "First person" }>First Page</Link> and then in the component FirstPage.js I need to read the name state so I have tried the following:

import React from "react";

export default props => {
  React.useEffect(() => {
    console.log(props)
  }, []);
  return (
    <div>
      <h1>First Page</h1>
      <p>Welcome to first page, {props.location.state.name}</p>
    </div>
  );
};

I have been reading React Router location documentation and it should pass the state as a component property but it isn't. I am quite sure there is something I am doing wrong or not seeing at all.

In case you wanna give a try on the whole code, I will leave here a CodeSandbox project to "test" this.

Therefore, any ideas on what am I doing wrong? Thanks in advance.

2 Answers

This isn't an issue of class-based vs. functional component, but rather how Routes work. Wrapped children don't receive the route params, but anything rendered using the Route's component, render, or children prop do.

Route render methods

<Switch>
  <Route path="/first-page" component={FirstPage} />
  <Route path="/second-page" component={SecondPage} />
</Switch>

Edit pedantic-banzai-dhz27

The other option is to export a decorated page component using the withRouter HOC, or if a functional component, use hooks.

withRouter

You can get access to the history object’s properties and the closest <Route>'s match via the withRouter higher-order component. withRouter will pass updated match, location, and history props to the wrapped component whenever it renders.

const FirstPage = props => {
  React.useEffect(() => {
    console.log(props)
  }, []);

  return (
    <div>
      <h1>First Page</h1>
      <p>Welcome to first page, {props.location.state.name}</p>
    </div>
  );
};

export default withRouter(FirstPage);

hooks

React Router ships with a few hooks that let you access the state of the router and perform navigation from inside your components.

const FirstPage = props => {
  const location = useLocation();

  console.log(location);

  return (
    <div>
      <h1>First Page</h1>
      <p>Welcome to first page, {location.state.name}</p>
    </div>
  );
};

export default FirstPage;

I found a problem in your router. Instead of using:

 <Route path="/first-page">
    <FirstPage/>
 </Route>

Use:

<Route path="/first-page" component={FirstPage}/>

Otherwise use the hook provided by the library let location = useLocation();, this way you will have access to the location object.

Related