[Next.js][App router]將URL參數的訊息顯示在網頁中Typescript

使用URL的參數(URL parameter)來顯示訊息是一種方便的作法。在SPA中也能使用,不需要有後端server的幫助。

這裡整理React.js和Next.js中用URL parameter來顯示訊息的方法,由於Next.js App router,這裡會都演示一次。


後端方面,稱為Query Parameter,在express等框架中使用req.query來存取

而web前端方面,則會用Search Parameter,是因為有了Web API: URLSearchParams

1. 以React來寫

import * as React from 'react';
import Typography from '@mui/material/Typography';

export default function App() {
const [message, setMessage] = React.useState<string>();

React.useEffect(() => {
const params = new URLSearchParams(window.location.search);
const t = params.get('type') || '不明錯誤';
const m = params.get('message') || '無更多細節資訊';
setMessage(`${t} : ${m}`);
}, []);

return (
<Typography>{message}</Typography>
);
}


因Next.js的App router為有Server Component和Client Component兩種寫法所以

2. 以App router的Server Component來寫

放置在src/app/error/page.tsx
import Typography from '@mui/material/Typography';

type Props = {
searchParams: { [key: string]: string | string[] | undefined };
};

export default function ErrorPage({ searchParams }: Props) {
const type = searchParams['type'] || '不明錯誤';
const message = searchParams['message'] || '無更多細節資訊';
return (
<Typography>
{`${type} : ${message}`}
</Typography>
);
}

透過Next.js提供的searchParams屬性就能取得所需的訊息資料,再透過簡單字串組合就能生成想要的訊息。


3. 以App router的Client Component來寫

放置在src/app/error/page.tsx
'use client';

import * as React from 'react';
import Typography from '@mui/material/Typography';
import { useSearchParams } from 'next/navigation';

function MessageBoard() {
const [message, setMessage] = React.useState<string>();
const params = useSearchParams();
React.useEffect(() => {
if (params) {
const t = params.get('type') || '不明錯誤';
const m = params.get('message') || '無更多細節資訊';
setMessage(`${t} : ${m}`);
}
}, [params]);
return (<Typography>{message}</Typography>);
}

export default function ErrorPage() {
return (
<React.Suspense fallback={<div>Loading...</div>}>
<MessageBoard />
</React.Suspense>
);
}

這裡多出了Suspense是因為Next.js生成靜態網頁時會建議

useSearchParams() should be wrapped in a suspense boundary at page


如果你想要套用第一個現成React的寫法,會發現next.js在build的時候會出現無法理解的錯誤,所以建議你若要套用現成寫法,請將元件設定成'use client',如此一來會減少你很多debug的時間。

留言