Next.js useRouter使用问题:如何动态拼接indexUrl至URL列表
问题描述
首次使用Next.js的useRouter,对其用法不熟悉。需要将通过路由传递的indexUrl动态拼接到指定URL列表中,尝试多种写法均报错:
尝试代码1
import { useRouter } from "next/router"; const Component = () => { const router = useRouter(); const { query: { indexUrl }, } = router; const props = { indexUrl, }; return props.indexUrl; }; export const urls = [ { url: "click.myyellowlocal.com/k.php?ai=19202&url=http%3a%2f%2f" + Component, }, { url: "cse.google.vu/url?q=https%3A%2F%2", }, { url: "sazhs.co.kr/member/login.html?noMemberOrder=&returnUrl=http%3a%2f%2", }, ];
此前尝试的写法
import { useRouter } from "next/router"; const router = useRouter(); const { query: { indexUrl }, } = router; const props = { indexUrl, }; export const urls = [ { url: "click.myyellowlocal.com/k.php?ai=19202&url=http%3a%2f%2f" + props.indexUrl, }, { url: "cse.google.vu/url?q=https%3A%2F%2", }, { url: "sazhs.co.kr/member/login.html?noMemberOrder=&returnUrl=http%3a%2f%2", }, ];
触发错误:Cannot read properties of null (reading 'useContext')
后续修改
const Component = () => { const router = useRouter(); const { query: { indexUrl }, } = router; const props = { indexUrl, }; };
但不知如何将props.indexUrl注入URL列表。
补充:indexUrl由其他文件通过Router.push传递:
function sendProps() { Router.push({ // pathname: "/processUrl", pathname: "/urlList", query: { indexUrl }, }); }
请问如何获取props.indexUrl并动态添加到URL列表中?
解决方案
错误原因
useRouter是React钩子,只能在React函数组件内部调用,不能在组件外部直接使用。你之前在组件外调用useRouter,违反了钩子的使用规则,所以触发了useContext相关的错误。
正确实现方式
方式1:在组件内部直接生成URL列表
把URL列表的定义放到组件内部,拿到indexUrl后动态拼接:
import { useRouter } from "next/router"; const UrlListComponent = () => { const router = useRouter(); // 处理indexUrl可能为undefined的情况,加默认值 const indexUrl = router.query.indexUrl || ''; // 动态生成带indexUrl的URL列表 const urls = [ { url: `click.myyellowlocal.com/k.php?ai=19202&url=http%3a%2f%2f${indexUrl}`, }, { url: "cse.google.vu/url?q=https%3A%2F%2", }, { url: `sazhs.co.kr/member/login.html?noMemberOrder=&returnUrl=http%3a%2f%2${indexUrl}`, }, ]; // 示例:渲染URL列表为可点击链接 return ( <div> {urls.map((item, idx) => ( <a key={idx} href={`//${item.url}`} target="_blank" rel="noopener noreferrer" > {item.url} </a> ))} </div> ); }; export default UrlListComponent;
方式2:封装复用的URL生成函数
如果URL列表需要在多个地方复用,可以把它封装成一个接收indexUrl参数的函数,在组件内部调用:
// 单独文件(比如utils/urlGenerator.js) export const generateUrls = (indexUrl = '') => [ { url: `click.myyellowlocal.com/k.php?ai=19202&url=http%3a%2f%2f${indexUrl}`, }, { url: "cse.google.vu/url?q=https%3A%2F%2", }, { url: `sazhs.co.kr/member/login.html?noMemberOrder=&returnUrl=http%3a%2f%2${indexUrl}`, }, ];
然后在组件中使用:
import { useRouter } from "next/router"; import { generateUrls } from '../utils/urlGenerator'; const UrlListComponent = () => { const router = useRouter(); const indexUrl = router.query.indexUrl || ''; // 调用函数生成带indexUrl的列表 const urls = generateUrls(indexUrl); // 渲染逻辑... return ( <div> {urls.map((item, idx) => ( <a key={idx} href={`//${item.url}`} target="_blank" rel="noopener noreferrer"> {item.url} </a> ))} </div> ); }; export default UrlListComponent;
注意事项
- Next.js在客户端渲染时,路由
query参数可能在页面初始加载时为undefined(比如SSR/SSG场景下),所以一定要加默认值或者判断,避免拼接出undefined的无效URL。 - 不要在组件外部调用任何React钩子,包括
useRouter,必须遵守钩子的使用规则:只能在函数组件或自定义钩子内部调用。
内容的提问来源于stack exchange,提问作者Damn Free
相关产品推荐
相关产品推荐

