react-router 抛出 TypeError: useContext(...) 在使用 useHistory 时未定义

pup*_*eno 11 reactjs react-router react-hooks

在我自己的代码中,我尝试useHistory通过将其添加到导入来使用 react-router :

import {BrowserRouter as Router, Link, Route, Switch, useHistory} from "react-router-dom";
Run Code Online (Sandbox Code Playgroud)

然后在我的App()函数上用它定义一个变量:

let history = useHistory();
Run Code Online (Sandbox Code Playgroud)

当我这样做时,我收到错误:

TypeError: useContext(...) is undefined
Run Code Online (Sandbox Code Playgroud)

来自 react-router's hooks.js,具体线路是:

return useContext(Context).history;
Run Code Online (Sandbox Code Playgroud)

整个文件如下所示:

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;
}
Run Code Online (Sandbox Code Playgroud)

更多上下文:

在此处输入图片说明

我尝试访问React.useContext我自己的代码,它被定义并且它是一个函数。

任何想法可能会发生什么?

小智 8

我认为您应该使用 BrowserRouter(作为路由器)将您的应用程序包装在 index.js 中,然后在您的应用程序中定义交换机和路由。因为您不能在使用 BrowserRouter 的同一文件中使用 useHistory 或 useLocation。因此,使用 BrowserRouter 包装器上一层。


Sol*_*tos 5

发生这种情况是因为您需要将组件包装在Router元素中。例如:

import React from 'react';
import { Router } from 'react-router-dom';
import { createBrowserHistory } from 'history';
// import MyComponent

const history = createBrowserHistory();

const MyApp = ()=> (
  <Router {...{ history }}>
    <MyComponent />
  </Router>
);

export default MyApp;
Run Code Online (Sandbox Code Playgroud)


Ass*_*saf 0

我也遇到过类似的问题useRouteMatch()。我不确定原因是否相同。在调用我的测试时,我收到了Cannot read property 'match' of undefined来自线路的错误。useContext(Context).match;useRouteMatch()


选项1:

useContext 返回未定义的方法之一是提供给 useContext 的 Context 不包含任何数据。例如,如果您value={{ name: "Pupeno" }}https://codesandbox.io/s/react-hooks-usecontext-example-wv76d?file=/src/index.js:320-347中删除,您会看到类似的错误。

可能存在类似的错误react-router-dom,当从这些钩子调用上下文时,上下文可能为空。


选项2:

不看你的代码很难判断。它也可能类似于https://github.com/ReactTraining/react-router/issues/7332