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。按此规则改造代码:
- 修改
MyFunctions.js,将函数改为自定义Hook:
// 注意要解构导入useLocation import { useLocation } from "react-router-dom"; // 函数名以use开头,符合自定义Hook命名规范 export function useUrl() { const location = useLocation(); return location.pathname + location.search; }
- 调整
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,再传入工具函数处理:
- 修改
MyFunctions.js,接收location参数:
export function getUrl(location) { return location.pathname + location.search; }
- 调整
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
相关产品推荐
相关产品推荐

