iT邦幫忙

2022 iThome 鐵人賽

DAY 27
0
自我挑戰組

我與 React 的 30天系列 第 27

Day 27 Next.js 用動態路徑做更多事

  • 分享至 

  • xImage
  •  

昨天我們介紹了關於 Next.js 的路徑種類,今天我們將實作用 API 獲取資料,並且實現換頁並且獲取不同資料

需求

假設我們現在在網站的後台

  1. 我們會一個頁面是 users 會呈現所有使用者列表,會顯示使用者的名稱
  2. 我們點擊其中一個使用者名稱,會到使用者的詳細資訊頁面

那讓我們看看要如何用 API 去實現這個步驟

先從路徑開始

首先我們會有需要一個 /users 的頁面去呈現所有使用者列表
再來我們希望每個使用者都有詳細資訊的頁面,所以我會這樣去設計我的路徑 /users/使用者的id

所以路徑結構如下

完成 users 頁面

再來我們到 pages/users/index/jsx 去完成我們要的畫面

這邊我們使用 jsonplaceholder 提供的 API 去獲取使用者的假資料

  • 我們可以將 css 寫在 styles/globals.css 裡面
  • 我們使用 useEffect & useState 去獲取 API 資料,並且放在 users 變數中
  • 並且在使用 map 將每個使用者呈現出來
  • 我們在 Linkhref 放入 users/${user.id},因為我們已經做好了動態路徑,也就是pages/users/[id].jsx,所以他會依照 user.id 去生成各個使用者頁面

明天我們將會提到 Link 以及 為何要 使用 isLoading 的個變數,今天我們就專注再如何獲取資料,並實踐換頁

// pages/users/index.jsx
import Link from "next/link"
import { useEffect, useState } from "react"

const Page = () =>{
  const [users, setUsers] = useState([])
  const [isLoading, setLoading] = useState(true)

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/users')
    .then(response => response.json())
    .then(json => {
      setUsers(json)
      setLoading(false)
    })
  
  },[users])

  if (isLoading) return <p>Loading...</p>
  if (!users) return <p>No profile data</p>

  return (
    <>
    <h1>使用者總頁面</h1>
    <div className="container">
      {users.map((user) => (
        <Link key={user.id} href={`users/${user.id}`}>
          <div className="userList">
            <a>
              {user.id}
              <div>{user.name}</div>
            </a>
          </div>
        </Link>
      ))}
    </div>
    </>
  )
}

export default Page

完成 users/id 頁面

再來我們要去完成各個使用者的,還記得在 Next.js 中要如何得到路徑上的id 嗎?

  • 使用 useRouter() 去取得 query 中的 id
  • 一樣使用配合 useEffect & useState 去獲取 API 資料,並且放在 info
  • 記得在 useEffect 中需要先去判斷 if (id) 是否存在,因為 Next.js 在初次渲染時 query 是空物件,之後的渲染才會 得到 query中的值
  • 否則你會送出一個 undefined 出去


// pages/users/[id].jsx
import Link from "next/link"
import { useRouter } from "next/router"
import { useEffect, useState } from "react"

const Page = () =>{
  const router = useRouter()
  const id = router.query.id
  const [info, setInfo] = useState([])
  const [isLoading, setLoading] = useState(true)

  useEffect(() => {
    if (id) {
      fetch(`https://jsonplaceholder.typicode.com/users/${id}`)
      .then(response => response.json())
      .then(json => {
        setInfo(json)
        setLoading(false)
      })
    }

  },[id])

  if (!id) return <></>;
  if (isLoading) return <h2>...isLoading</h2>;
  
  return (
    <div>
      <h1>{info.name} 的頁面</h1>
      <h2>{info.email}</h2>
      <h2>{info.phone}</h2>
      <Link href="/users">
        <a>返回使用者列表</a>
      </Link>
    </div>
  )
}
export default Page

小結

今天使用動態路徑,來實現依據不同的頁面打不同的 API,而這都是將 query 中的值取出來,來做到的,明天會針對 Next.js 做更多介紹


上一篇
Day 26 Next.js 之路徑種類
下一篇
Day 28 Next.js 之 Link Component
系列文
我與 React 的 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Robert Chang
iT邦新手 3 級 ‧ 2022-10-13 00:46:18

更多的介紹在哪?

zhan0217 iT邦新手 4 級 ‧ 2022-10-13 02:50:41 檢舉

剛剛發了喔,可以去觀看了
謝謝你的支持

我要留言

立即登入留言