Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react-router throwing TypeError: useContext(...) is undefined when using useHistory

On my own code I tried to use react-router's useHistory by adding it to the imports:

import {BrowserRouter as Router, Link, Route, Switch, useHistory} from "react-router-dom";

and then defining a variable with it on my App() function:

let history = useHistory();

When I do that, I get the error:

TypeError: useContext(...) is undefined

coming from react-router's hooks.js, the specific line is:

return useContext(Context).history;

The whole file looks like this:

import React from "react";
import invariant from "tiny-invariant";

import Context from "./RouterContext.js";
import matchPath from "./matchPath.js";

const useContext = React.useContext;

export function useHistory() {
  if (__DEV__) {
    invariant(
      typeof useContext === "function",
      "You must use React >= 16.8 in order to use useHistory()"
    );
  }

  return useContext(Context).history;
}

export function useLocation() {
  if (__DEV__) {
    invariant(
      typeof useContext === "function",
      "You must use React >= 16.8 in order to use useLocation()"
    );
  }

  return useContext(Context).location;
}

export function useParams() {
  if (__DEV__) {
    invariant(
      typeof useContext === "function",
      "You must use React >= 16.8 in order to use useParams()"
    );
  }

  const match = useContext(Context).match;
  return match ? match.params : {};
}

export function useRouteMatch(path) {
  if (__DEV__) {
    invariant(
      typeof useContext === "function",
      "You must use React >= 16.8 in order to use useRouteMatch()"
    );
  }

  return path
    ? matchPath(useLocation().pathname, path)
    : useContext(Context).match;
}

Some more context:

enter image description here

I tried accessing React.useContext on my own code and it is defined and it is a function.

Any ideas what might be going on here?

like image 872
pupeno Avatar asked May 11 '20 05:05

pupeno


1 Answers

I think that you should wrap your App in index.js with the BrowserRouter (as Router) and then in your App you define the Switch and Routes. Because you cannot use useHistory or useLocation in the same file where you use BrowserRouter. So, use BrowserRouter wrapper one level up.

like image 93
Gherghel Andrei Avatar answered Sep 22 '22 03:09

Gherghel Andrei