- Next.js คืออะไร? + มาหัดเขียนเว็บด้วย Next.js กันดีกว่า
- ตอนที่ 1 - Hello Next.js เริ่มสร้างโปรเจ็ค
- ตอนที่ 2 - สร้าง Page และการ navigate ระหว่าง Pages
- ตอนที่ 3 - การจัดการ Assets, Metadata และ CSS
- ตอนที่ 4 - เรื่องของ Pre Rendering
- ตอนที่ 5 - Data Fetching และการดึงข้อมูลจาก API
- ตอนที่ 6 - การทำ Dynamic Routes
- ตอนที่ 7 - API Routes การทำ API ด้วย Next.js
ตอนที่ 5 - Data Fetching และการดึงข้อมูลจาก API
เขียนวันที่ : Jul 15, 2022
ตอนนี้จะเป็นเรื่องของ Fetching API เพื่อดึงข้อมูลจาก API มาแสดง ซึ่งจริงๆ แล้ว fetching data นั้นทำได้หลายท่ามากๆ เช่น
- Client Side - ด้วยการใช้
useEffect()
และทำการfetch
แบบเดียวกับท่า React.js ธรรมดาครับ - Server Side - ด้วย
getServerSideProps
จะทำการ fetch data ทุกๆ ครั้งที่มีการเรียก request (รันที่ server) - Hybrid - ทั้ง Incremental Static Regenration (ISR) และ Static Site Generation (SSG)
ซึ่งแบบ Client Side เราจะขอข้ามไปนะครับ จะพูดถึงเฉพาะที่ใช้ใน Next.js เท่านั้น
getServerSideProps
- เป็นการ fetch ข้อมูลฝั่ง Server คือจะทำการ fetch api ทุกๆครั้ง ที่เราทำการ request หน้าเว็บนั้นๆ
- return เป็น JSON เพื่อใช้สำหรับ pre-render Page (จะเป็นค่า props ที่ให้เราเรียกใช้งานใน component)
ตัวอย่างการใช้งาน เช่น ผมสร้างไฟล์ hello.js
ขึ้นมา ใน pages
function Hello({ title }) {
return <p>{title}</p>
}
export async function getServerSideProps(context) {
return {
props: { title: 'This is title from getServerSideProps' },
}
}
export default Hello
ลอง start server
yarn dev
และดูผลลัพธ์ครับ http://localhost:3000/hello
getStaticProps
getStaticProps
หรือ Static Site Generation ตัว Next.js จะทำการ pre-render หน้า page โดยใช้ props ที่ return จาก getStaticProps
ครับ
export async function getStaticProps(context) {
return {
props: {}
}
}
- ใช้
getStaticProps
เมื่อเราต้องการ data จาก API - เมื่อต้องการ pre-render เพื่อรองรับ SEO
- ตัว
getStaticProps
รันฝั่ง Server (ตอน build time) หรือรัน background ถ้าเราใช้revalidate
ตัวอย่างการใช้ getStaticProps
เพื่อดึงข้อมูล API ตัวอย่าง ผมทำการ fetch api posts จาก https://jsonplaceholder.typicode.com/posts และก็ return props
ไปให้ Posts
ใช้เพื่อ render html ครับ
function Posts({ posts }) {
return (
<div>
<h2>Posts</h2>
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
)
}
export async function getStaticProps() {
const res = await fetch('https://jsonplaceholder.typicode.com/posts')
const posts = await res.json()
return {
props: {
posts,
},
}
}
export default Posts
Incremental Static Regeneration (ISR)
จริงๆ มันก็คือการใช้ getStaticProps
ที่เป็นเวอร์ชั่น upgrade ครับ โดยการเพิ่ม option revalidate
การทำงานของมันคือ ปกติ getStaticProps
จะทำงานแค่ Server side เวลา request จะไม่รันแล้ว นอกจาก เราจะใส่ revalidate
ตัว Next.js จะทำการ trigger และทำการ rebuild (หรือเรียก getStaticProps
ให้เราเอง เป็น Background process)
ตัวอย่าง เดิมของ getStaticProps
แต่เพิ่ม revalidate
ให้มัน ทำการ refresh ทุกๆ 5วิ โดยผมตั้งชื่อให้มันว่า meow.js
import Image from 'next/image'
function Meow({ meow }) {
return (
<div>
<h2>Meow</h2>
<Image src={meow.url} width="300" height="300" alt={meow.file} />
</div>
)
}
export async function getStaticProps() {
const res = await fetch('https://meow.senither.com/v1/random')
const response = await res.json()
return {
props: {
meow: response.data,
},
revalidate: 5,
}
}
export default Meow
เนื่องจากตัวอย่าง ผมใช้ <Image>
ของ Next.js เพื่อ render image ซึ่งตัว url มาจากเว็บ meow.senither
ตัว default ของ Next ไม่สามารถ hotlink ได้ครับ ต้องทำการเพิ่มใน next.config.js
ก่อน
module.exports = {
images: {
domains: ['meow.senither.com'],
},
}
วิธีทดสอบคือ เราต้องทำการ build ก่อนครับ (เพราะว่า yarn dev
มันจะเรียก getStaticProps
ทุกๆครั้งที่ request เลยเทสไม่ได้ ต้อง build เพื่อให้เป็น production mode) ซึ่งเวลาเรารัน build
yarn build
เราจะเห็นผลลัพธ์หน้า pages ของเรา ว่าเป็น ISR และมี revalidate กี่วินาทีบอกไว้ ประมาณนี้
├ ● /meow (ISR: 5 Seconds) (430 ms) 354 B 83.4 kB
จากนั้นสั่ง
yarn start
เข้าหน้าเว็บ http://localhost:3000/meow จากนั้น refresh รัวๆ จะเห็นว่ามันจะได้รูปเดิม (เพราะว่าถูก build ครั้งแรก) จนกว่าจะครบ 5วิ มันก็จะเรียก getStaticProps
และก็จะได้รูปใหม่ ไปเรื่อยๆ ทุกๆ 5 วิ
🎉 จบแล้วครับ สำหรับตอนที่ 5 - เรื่องของ Data Fetching เบื้องต้นก็มีประมาณนี้ครับ เดี๋ยวในตอนต่อไป จะพูดถึง Dynamic Routes เราก็จะได้ใช้ Data Fetching เพื่อให้เห็นภาพจริงๆมากขึ้น รวมถึง getStaticPaths
ที่ยังไม่ได้พูดไปด้วยครับ
คำถาม
- ถ้า
getServerSideProps
render แล้ว error ตัว Next.js จะ show หน้าไหน (ไฟล์ไหน)? - เราสามารถ cached Server-Side Rendering ได้มั้ย ถ้าได้ทำยังไง?
getStaticProps
สามารถ export หน้าอื่นๆ เช่น components หรือ_app
หรือ_document
ได้มั้ย?