Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

useParams hook returns undefined in react functional component

The app displays all photos <Photo> in a grid <PhotoGrid>, then once clicked, a function in <Photo> changes URL with history.push, and Router renders <Single> based on URL using useParams hook.

PhotoGrid -> Photo (changes URL onClick) -> Single based on URL (useParams). I must have messed something up, becouse useParams returns undefined.

Thanks for all ideas in advanced. App.js

class App extends Component {
  render() {
    return (
      <>
        <Switch>
          <Route exact path="/" component={PhotoGrid}/>
          <Route path="/view/:postId" component={Single}/>
        </Switch>
      </>
    )
  }
}
export default App;

Photogrid.js

export default function PhotoGrid() {
    const posts = useSelector(selectPosts);

    return (
        <div>
            hi
            {/* {console.log(posts)} */}
            {posts.map((post, i) => <Photo key={i} i={i} post={post} />)}
        </div>
    )
}

in Photo I change URL with history.push

const selectPost = () => {
  (...)
  history.push(`/view/${post.code}`);
  };

Single.js

import { useParams } from "react-router-dom";
export default function Single() {
    let { id } = useParams();
    console.log("id:",  id)   //returns undefined

    return (
      <div className="single-photo">
       the id is: {id} //renders nothing
      </div>
    )
}
like image 620
Przemek Avatar asked Mar 20 '26 14:03

Przemek


2 Answers

When using useParams, you have to match the destructure let { postId } = useParams(); to your path "/view/:postId".

Working Single.js

import { useParams } from "react-router-dom";

export default function Single() {
    const { postId } = useParams();
    console.log("this.context:",  postId )

    return (
      <div className="single-photo">
        {/* render something based on postId */}
      </div>
    )
}
like image 73
Szabó Sebestyén Avatar answered Mar 23 '26 08:03

Szabó Sebestyén


You should use the same destructure as mentioned in your Route path. In this case, you should have written :

let { postID } = useParams();

I will mention two more mistakes which someone could make and face the same problem:

  1. You might use Router component in place of Route component.
  2. You might forget to mention the parameter in the path attribute of the Route component, while you would have mentioned it in the Link to component.
like image 35
evasharma12 Avatar answered Mar 23 '26 08:03

evasharma12



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!