Next.js 新手常見錯誤
哈囉各位開發者朋友們!今天我們要來聊聊 Next.js 這個超強大的 React 框架。雖然它很棒,但對新手來說,還是有一些常見的陷阱和錯誤。今天我會用輕鬆的方式帶你們看看這些錯誤,讓你們能夠順利避開它們!
Youtube影片來源
1. 忘記配置 next.config.js
這是很多新手最常犯的錯誤之一。Next.js 的配置檔案 next.config.js
是非常重要的,它可以設定很多關鍵的選項。如果你忘記配置這個檔案,可能會遇到一些預期之外的行為。
解決方法
確保你有正確地配置 next.config.js
,例如:
// next.config.js
module.exports = {
reactStrictMode: true,
images: {
domains: ['example.com'],
},
};
2. 使用客製化路由但忘記更新連結
有時候我們會需要客製化路由,但如果你忘記更新應用中的連結,使用者就會遇到 404 錯誤。
解決方法
確保你在更新路由後,也同步更新所有相關的連結。
// pages/product/[id].js
import { useRouter } from 'next/router';
const ProductPage = () => {
const router = useRouter();
const { id } = router.query;
return <div>Product ID: {id}</div>;
};
export default ProductPage;
3. 忘記安裝必要的依賴
Next.js 使用很多外部套件,如果你忘記安裝這些依賴,應用程式就無法正常運作。
解決方法
記得在專案中執行以下命令安裝必要的套件:
npm install next react react-dom
4. 沒有正確配置靜態資源
Next.js 允許你使用 /public
資料夾來存放靜態資源,但如果你沒有正確配置,這些資源就無法被正確載入。
解決方法
確保你的靜態資源放在 /public
資料夾,並以正確的方式引用它們。
<img src="/images/logo.png" alt="Logo" />
5. 忽略錯誤處理
開發過程中難免會遇到錯誤,如果你忽略這些錯誤或沒有適當處理,會對使用者體驗造成很大的影響。
解決方法
使用 Next.js 提供的錯誤處理機制,例如 getInitialProps
中的錯誤處理。
// pages/_error.js
function Error({ statusCode }) {
return (
<p>
{statusCode
? `An error ${statusCode} occurred on server`
: 'An error occurred on client'}
</p>
);
}
Error.getInitialProps = ({ res, err }) => {
const statusCode = res ? res.statusCode : err ? err.statusCode : 404;
return { statusCode };
};
export default Error;
6. 沒有優化效能
即使 Next.js 已經非常快,但還是有一些效能優化的工作需要我們去做。例如,沒有使用 lazy loading 來延遲載入非必要的資源。
解決方法
使用 Next.js 的 next/dynamic
來實現動態載入。
import dynamic from 'next/dynamic';
const DynamicComponent = dynamic(() => import('../components/DynamicComponent'), {
ssr: false,
});
const Home = () => (
<div>
<DynamicComponent />
</div>
);
export default Home;
7. 沒有適當處理 SEO
SEO(搜尋引擎最佳化)對於每個網站都非常重要,但很多新手會忽略這一點。
解決方法
使用 Next.js 的 next/head
組件來設定適當的 meta 標籤。
import Head from 'next/head';
const Home = () => (
<div>
<Head>
<title>My Next.js App</title>
<meta name="description" content="This is a Next.js app" />
</Head>
<h1>Welcome to my Next.js app!</h1>
</div>
);
export default Home;
8. 沒有利用靜態生成
Next.js 提供了靜態生成(Static Generation)和伺服器端渲染(Server-Side Rendering)兩種模式,但很多新手只使用伺服器端渲染,忽略了靜態生成的優點。
解決方法
在適當的情況下使用 getStaticProps
和 getStaticPaths
來實現靜態生成。
// pages/posts/[id].js
export async function getStaticPaths() {
// Return a list of possible value for id
const paths = [
{ params: { id: '1' } },
{ params: { id: '2' } },
];
return { paths, fallback: false };
}
export async function getStaticProps({ params }) {
// Fetch necessary data for the blog post using params.id
return {
props: {
post: { id: params.id, title: `Post ${params.id}` },
},
};
}
const Post = ({ post }) => {
return (
<div>
<h1>{post.title}</h1>
<p>This is the blog post content.</p>
</div>
);
};
export default Post;
9. 未善用 next/image
組件
Next.js 提供的 next/image
組件可以幫助你優化圖片的加載,但很多新手仍然使用普通的 HTML <img>
標籤。
解決方法
使用 next/image
組件來替代 <img>
標籤,享受自動優化的好處。
import Image from 'next/image';
const Home = () => (
<div>
<Image src="/images/logo.png" alt="Logo" width={500} height={500} />
</div>
);
export default Home;
10. 忽略環境變數設定
環境變數在應用程式開發中非常重要,但很多新手不知道如何在 Next.js 中正確使用它們。
解決方法
在根目錄下創建 .env.local
文件,並將環境變數存放在其中。
NEXT_PUBLIC_API_URL=https://api.example.com
然後在程式碼中使用它們:
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
11. 沒有配置 ESLint 和 Prettier
代碼風格和品質對於一個項目來說非常重要,但很多新手會忽略配置 ESLint 和 Prettier。
解決方法
安裝並配置 ESLint 和 Prettier:
npm install eslint prettier eslint-plugin-prettier eslint-config-prettier --save-dev
創建 .eslintrc.json
文件:
{
"extends": ["next", "prettier"]
}
創建 .prettierrc
文件:
{
"singleQuote": true,
"semi": false
}
12. 忘記使用 useEffect
處理副作用
在 React 中,useEffect
是用來處理副作用的,但很多新手會忘記使用它,導致無法正確處理數據加載等操作。
解決方法
在需要處理副作用的地方使用 useEffect
:
import { useEffect, useState } from 'react';
const Home = () => {
const [data, setData] = useState(null);
useEffect(() => {
fetch('/api/data')
.then((res) => res.json())
.then((data) => setData(data));
}, []);
return <div>{data ? <p>{data.message}</p> : <p>Loading...</p>}</
div>;
};
export default Home;
13. 沒有使用 getServerSideProps
獲取伺服器端數據
當你需要在伺服器端獲取數據時,getServerSideProps
是非常有用的,但很多新手會忽略它的使用。
解決方法
在需要伺服器端數據的頁面使用 getServerSideProps
:
export async function getServerSideProps() {
const res = await fetch('https://api.example.com/data');
const data = await res.json();
return {
props: { data },
};
}
const Home = ({ data }) => {
return <div>{data.message}</div>;
};
export default Home;
14. 沒有設定自定義 404 頁面
當用戶訪問不存在的頁面時,顯示一個友好的 404 頁面是非常重要的。
解決方法
在 pages
目錄下創建 404.js
文件:
const Custom404 = () => {
return <h1>404 - Page Not Found</h1>;
};
export default Custom404;
15. 忽略使用 next/link
進行路由導航
Next.js 提供的 next/link
可以優化路由導航,但很多新手仍然使用傳統的 <a>
標籤。
解決方法
使用 next/link
來替代 <a>
標籤:
import Link from 'next/link';
const Home = () => (
<div>
<Link href="/about">
<a>About</a>
</Link>
</div>
);
export default Home;
16. 忽略頁面的 getInitialProps
在某些情況下,你需要在伺服器端和客戶端獲取數據,此時 getInitialProps
就非常有用了。
解決方法
在頁面組件中使用 getInitialProps
:
const Page = ({ data }) => {
return <div>{data.message}</div>;
};
Page.getInitialProps = async () => {
const res = await fetch('https://api.example.com/data');
const data = await res.json();
return { data };
};
export default Page;
17. 沒有處理 API 路由的錯誤
在開發 API 路由時,忽略錯誤處理會導致難以排除問題。
解決方法
在 API 路由中添加錯誤處理:
export default async (req, res) => {
try {
const data = await fetch('https://api.example.com/data').then((res) =>
res.json()
);
res.status(200).json(data);
} catch (error) {
res.status(500).json({ error: 'Failed to fetch data' });
}
};
18. 忽略 getStaticProps
的 ISR 功能
增量靜態再生(ISR)可以讓靜態頁面在背景中自動更新,但很多新手會忽略這個功能。
解決方法
在 getStaticProps
中使用 revalidate
屬性:
export async function getStaticProps() {
const res = await fetch('https://api.example.com/data');
const data = await res.json();
return {
props: { data },
revalidate: 10, // 每 10 秒重新生成一次
};
}
const Home = ({ data }) => {
return <div>{data.message}</div>;
};
export default Home;
19. 忽略 useRouter
處理路由事件
useRouter
可以讓你在組件中訪問路由對象,但很多新手會忽略它的使用。
解決方法
在需要訪問路由資訊的組件中使用 useRouter
:
import { useRouter } from 'next/router';
const Home = () => {
const router = useRouter();
return <div>Current route: {router.pathname}</div>;
};
export default Home;
20. 忽略 next/script
設定第三方腳本
Next.js 提供的 next/script
可以幫助你更好地管理第三方腳本,但很多新手會忽略它的使用。
解決方法
使用 next/script
來管理第三方腳本:
import Script from 'next/script';
const Home = () => (
<div>
<Script
src="https://www.googletagmanager.com/gtag/js?id=GA_TRACKING_ID"
strategy="afterInteractive"
/>
<Script id="google-analytics" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'GA_TRACKING_ID');
`}
</Script>
<h1>Welcome to my Next.js app!</h1>
</div>
);
export default Home;
21. 忽略 next/head
設定頁面標題
每個頁面應該有不同的標題和 meta 標籤,但很多新手會忽略這一點。
解決方法
在每個頁面組件中使用 next/head
設定頁面標題和 meta 標籤:
import Head from 'next/head';
const Home = () => (
<div>
<Head>
<title>Home Page</title>
<meta name="description" content="This is the home page" />
</Head>
<h1>Welcome to the Home Page!</h1>
</div>
);
export default Home;
22. 忽略 getStaticPaths
設定動態路由
在動態路由中使用 getStaticPaths
可以生成靜態頁面,但很多新手會忽略這一點。
解決方法
在動態路由頁面中使用 getStaticPaths
:
export async function getStaticPaths() {
const res = await fetch('https://api.example.com/posts');
const posts = await res.json();
const paths = posts.map((post) => ({
params: { id: post.id.toString() },
}));
return { paths, fallback: false };
}
export async function getStaticProps({ params }) {
const res = await fetch(`https://api.example.com/posts/${params.id}`);
const post = await res.json();
return { props: { post } };
}
const Post = ({ post }) => {
return (
<div>
<h1>{post.title}</h1>
<p>{post.content}</p>
</div>
);
};
export default Post;
23. 忽略使用 SWR
進行數據獲取
SWR 是一個用於數據請求的 React Hook 庫,能夠自動處理數據快取和重新驗證。但很多新手會忽略它的使用。
解決方法
使用 SWR
進行數據獲取:
import useSWR from 'swr';
const fetcher = (url) => fetch(url).then((res) => res.json());
const Home = () => {
const { data, error } = useSWR('/api/data', fetcher);
if (error) return <div>Failed to load</div>;
if (!data) return <div>Loading...</div>;
return <div>{data.message}</div>;
};
export default Home;
24. 忽略 next/font
設定自定義字體
Next.js 提供的 next/font
可以幫助你更好地管理自定義字體,但很多新手會忽略它的使用。
解決方法
使用 next/font
來管理自定義字體:
import { createGlobalStyle } from 'styled-components';
import { OpenSans } from 'next/font/google';
const openSans = OpenSans({
weight: '400',
subsets: ['latin'],
});
const GlobalStyle = createGlobalStyle`
body {
font-family: '${openSans.style.fontFamily}', sans-serif;
}
`;
const Home = () => (
<div>
<GlobalStyle />
<h1>Welcome to my Next.js app!</h1>
</div>
);
export default Home;
25. 忽略使用 Image Optimization
Next.js 提供的 Image Optimization
可以自動優化圖片,但很多新手會忽略這一點。
解決方法
使用 next/image
來自動優化圖片:
import Image from 'next/image';
const Home = () => (
<div>
<Image src="/images/logo.png" alt="Logo" width={500} height={500} />
</div>
);
export default Home;
26. 忽略 next/router
處理導航事件
next/router
可以幫助你處理
導航事件,但很多新手會忽略它的使用。
解決方法
在需要處理導航事件的地方使用 next/router
:
import { useRouter } from 'next/router';
const Home = () => {
const router = useRouter();
const handleClick = () => {
router.push('/about');
};
return <button onClick={handleClick}>Go to About Page</button>;
};
export default Home;
27. 忽略 Static File Serving
Next.js 允許你在 public
目錄下放置靜態文件,但很多新手會忽略這一點。
解決方法
將靜態文件放在 public
目錄下,並以 /public
作為根路徑引用它們:
<img src="/images/logo.png" alt="Logo" />
28. 忽略 Middleware
Next.js 提供的 Middleware
可以讓你在請求處理過程中插入自定義邏輯,但很多新手會忽略它的使用。
解決方法
在 pages/_middleware.js
文件中添加自定義邏輯:
export default function middleware(req, ev) {
const { pathname } = req.nextUrl;
if (pathname === '/') {
return new Response('Hello, world!');
}
}
29. 忽略 API Route
錯誤處理
在開發 API 路由時,忽略錯誤處理會導致難以排除問題。
解決方法
在 API 路由中添加錯誤處理:
export default async (req, res) => {
try {
const data = await fetch('https://api.example.com/data').then((res) =>
res.json()
);
res.status(200).json(data);
} catch (error) {
res.status(500).json({ error: 'Failed to fetch data' });
}
};
希望這些常見錯誤和解決方法能幫助你更順利地使用 Next.js!如果你有任何問題或想分享你的經驗,歡迎在下方留言喔!