22

I can't understand why it gives me the above error. I used the props way with props.match.params.languagename and it works just fine.

I did not include all imports in the code below.


import { useParams } from 'react-router';

const App = () => {
  const topicsState = useSelector(state => state.topics);

  const dispatch = useDispatch();
  const { languagename } = useParams();

  useEffect(() => {
    dispatch(fetchGitHubTrendingTopics());
  }, [dispatch]);

  const handleRepositoryPages = () => {
    const repositoryPages = topicsState.find(
      topicState => topicState.name === languagename
    );
    if (repositoryPages)
      return <RepositoryPage repositoryPages={repositoryPages} />;
  };
  return (
    <>
      <Router>
        <Header topics={topicsState} />
        <Switch>
          <Route path="/" exact>
            <Dashboard topics={topicsState} />
          </Route>
          <Route
            path="/language/:languagename"
            exact
            render={handleRepositoryPages()}
          />

          <Redirect to="/" />
        </Switch>
      </Router>
    </>
  );
};

3 Answers3

36

You can only use useParams in a component that is a child of your Router component, but App is the parent in your case.

The Router component injects the context containing the match into the tree below it which will be read by the useParams hook by internally using the useContext hook.

trixn
  • 15,761
  • 2
  • 38
  • 55
  • 6
    this is incorrect. The op imported from 'react-router'instead of 'react-router-dom' which is causing the issue. – Chris Matthews Mar 03 '21 at 04:23
  • 2
    @ChrisMatthews Actually I looked it up and what you are saying is not correct. `react-router` does export `useParams`. If that wouldn't be the case, OP would also have seen a different error message, that indicates there is no named export `useParams` in that module. – trixn Mar 03 '21 at 08:18
  • @ChrisMatthews Proof: https://codesandbox.io/s/staging-fog-eez2n?file=/src/App.js – trixn Mar 03 '21 at 08:28
  • Ran into exactly the same issue myself and @ChrisMatthews answer is correct. `useParams` from `react-router` is not the same as `useParams` from `react-router-dom` – lje Feb 28 '22 at 18:37
  • I was facing the same issue. I was trying to run my app from local then this error came up but while running the same app from hosted environment was working fine. As @ChrisMatthews commented changing import from from 'react-router' to 'react-router-dom' fixed the issue. – devanil Oct 26 '22 at 05:46
5

You can use this code , in jest test file for useParams .This worked for me

 jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useParams: jest.fn().mockReturnValue({ environment: 'dev', service: 'fakeService' }),
}))

Hope this works !

Payel Dutta
  • 742
  • 10
  • 23
3

For anyone else seeing this error from trying to use useParams to get Query/Search Parameters and not URL Parameters, you can use useLocation from react-router-dom

import { useLocation } from 'react-router-dom';
...
...
const query = new URLSearchParams(useLocation().search);
...

Difference between Query Parameters and URL Parameters

Query Parameter demo

Brwoser Support for URLSearchParams()

Muhammed Moussa
  • 4,589
  • 33
  • 27
piouson
  • 3,328
  • 3
  • 29
  • 29