Search code examples
reactjsurlparametersreact-hooksrouter

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>
    )
}

Solution

  • 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>
        )
    }