You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何在自定义文件中正确使用useLocation Hook?

React中在工具函数使用useLocation触发Hook规则错误的解决方法

问题

在React项目的MyFunctions.js工具文件中,尝试用useLocation Hook获取当前URL的pathname和查询字符串时,触发以下错误:

React Hook "useLocation" is called in function "getCurrentURL" that is neither a React function component nor a custom React Hook function.

相关代码

MyFunctions.js

import useLocation from "react-router-dom";

export function getUrl() {
  const location = useLocation();
  return location.pathname + location.search;
}

App.js

import "./styles.css";
import { HashRouter as Router, Route, Routes } from "react-router-dom";
import * as fn from "./MyFunctions";
import Test1 from "./components/Test1";

export default function App() {
  const a = fn.getUrl();

  return (
    <Router>
      <div className="App">
        <h1>Hello CodeSandbox: {a}</h1>
        <Routes>
          <Route path="/" element={<Test1 />} />
        </Routes>
      </div>
    </Router>
  );
}

Test1.js

const Test1 = () => {
  return (
    <div>
      <h1>Lorem Ipsum</h1>
    </div>
  );
};

export default Test1;

解决方法

方案1:将工具函数改为自定义Hook

React Hook规则要求:只有React函数组件或以use开头的自定义Hook才能调用Hook。按此规则改造代码:

  1. 修改MyFunctions.js,将函数改为自定义Hook:
// 注意要解构导入useLocation
import { useLocation } from "react-router-dom";

// 函数名以use开头,符合自定义Hook命名规范
export function useUrl() {
  const location = useLocation();
  return location.pathname + location.search;
}
  1. 调整App.js,确保在Router上下文内调用Hook:
import "./styles.css";
import { HashRouter as Router, Route, Routes } from "react-router-dom";
import { useUrl } from "./MyFunctions";
import Test1 from "./components/Test1";

export default function App() {
  // App组件在Router外部,无法访问Router上下文,所以新建内部组件嵌套在Router内
  return (
    <Router>
      <InnerApp />
    </Router>
  );
}

// 内部组件处于Router上下文范围内,可正常调用useUrl
function InnerApp() {
  const a = useUrl();
  return (
    <div className="App">
      <h1>Hello CodeSandbox: {a}</h1>
      <Routes>
        <Route path="/" element={<Test1 />} />
      </Routes>
    </div>
  );
}

方案2:传递location对象到工具函数

如果不想使用Hook,可在组件中先获取location,再传入工具函数处理:

  1. 修改MyFunctions.js,接收location参数:
export function getUrl(location) {
  return location.pathname + location.search;
}
  1. 调整App.js,在Router上下文内获取location并传入函数:
import "./styles.css";
import { HashRouter as Router, Route, Routes, useLocation } from "react-router-dom";
import { getUrl } from "./MyFunctions";
import Test1 from "./components/Test1";

export default function App() {
  return (
    <Router>
      <InnerApp />
    </Router>
  );
}

function InnerApp() {
  const location = useLocation();
  const a = getUrl(location);
  return (
    <div className="App">
      <h1>Hello CodeSandbox: {a}</h1>
      <Routes>
        <Route path="/" element={<Test1 />} />
      </Routes>
    </div>
  );
}

核心注意事项

  • 严格遵守React Hook规则:Hook只能在React函数组件或自定义Hook(命名以use开头)中调用。
  • useLocation依赖Router提供的上下文,必须在Router组件包裹的范围内调用,不能在Router外部的组件中直接使用。

内容的提问来源于stack exchange,提问作者dapidmini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 06:36:21