前一篇我們已經完成大致上所有的功能了,今天篇稍微調整一下 UI 畫面,並讓我們的選單有上下頁的功能。
我們已知回傳資料內有上下頁完整的 url 了,所以我們也利用了此特性,將原本的 url 做為參數帶入 function 做成可以重複運用的 funciton,那麼上下頁的邏輯就會變得很簡單,重複去使用相同的 fetchPokes 並帶入上下頁的 url 參數:
const pageClick = (url) => {
dispatch(fetchPokes(url))
}
如此一來,我們在使用 pageClick 的時候只要帶入對應的 url 即可,那麼我會將原本的 pokemons component 做以下修改:
// src/components/Pokemons.jsx
import React from 'react'
import { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { fetchPokes, selectPokemon } from '../features/slices/pokemonSlice'
const Pokemons = () => {
const pokemon = useSelector(selectPokemon)
const dispatch = useDispatch()
useEffect(() => {
if(pokemon.data.length === 0) {
dispatch(fetchPokes(`https://pokeapi.co/api/v2/pokemon?offset=0&limit=10`))
}
}, [pokemon.data.length])
console.log('pokeData', pokemon);
const pageClick = (url) => {
dispatch(fetchPokes(url))
}
return (
<div>
<h4>Pokemon List</h4>
<div className='f-c-c'>
<button
className='btn filled'
onClick={() => pageClick(pokemon.data?.previous)}
disabled={pokemon.data?.previous === null}
style={{padding: '.5rem', marginRight: '.5rem'}}
>
上一頁
</button>
<button
className='btn filled'
onClick={() => pageClick(pokemon.data?.next)}
disabled={pokemon.data?.next === null}
style={{padding: '.5rem'}}
>
下一頁
</button>
</div>
<div className='pokes-wrapper'>
{pokemon.data?.results?.map((pokemon) => (
<div key={pokemon.url} className='poke-item'>
<img
alt={pokemon.name}
width="200px"
// 這裡圖案的 url 是齊全的
src={`https://img.pokemondb.net/artwork/large/${pokemon.name}.jpg`}
/>
<p>{pokemon.name}</p>
</div>
))}
</div>
</div>
)
}
export default Pokemons
這邊會發現我將原本的 ul, li 替換成 div 了,因為我想讓畫面比較好看,讓每個寶可夢都呈現像一張卡片的樣子,所以我們回過頭來調整一下 CSS,讓我們回到 index.css,做以下調整:
* {
box-sizing: border-box;
margin: 0;
}
body {
padding: 0;
}
.container {
width: min(100%, 768px);
padding: 0 2rem;
margin: 0 auto;
}
.f-c-c {
display: flex;
justify-content: center;
align-items: center;
}
.pokes-wrapper {
display: grid;
gap: .5rem;
margin: .5rem 0;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
.poke-item {
display: flex;
justify-content: flex-end;
align-items: center;
flex-direction: column;
padding: .25rem;
border-radius: .5rem;
box-shadow: 2px 2px 8px #ccc;
}
.btn {
border: 0;
border-radius: .5rem;
cursor: pointer;
outline: 0;
display: inline-flex;
position: relative;
align-items: center;
vertical-align: middle;
justify-content: center;
text-decoration: none;
background-color: transparent;
transition: all 0.2s ease-in-out;
}
.btn:hover {
transition: all 0.2s ease-in-out;
filter: brightness(1.5);
}
.btn:active {
transition: all 0.2s ease-in-out;
filter: brightness(0.5);
}
.btn:disabled {
color: #aaa;
}
.filled {
background-color: indigo;
color: white;
}
這樣一來應該比較好看一點了吧!
這邊附上這個章節的 source code 。
那麼我們基本的應用就到這裡結束了,下一篇我會稍微分享一些關於 Redux toolkit Query 的使用情況,我會用簡單的 todolist 當範本介紹一下有關的用法!