iT邦幫忙

2022 iThome 鐵人賽

DAY 24
0
自我挑戰組

30天深入淺出Redux系列 第 24

Redux 深入淺出 - [ Day 24 ] React Redux Pokemon 換頁功能

  • 分享至 

  • xImage
  •  

前一篇我們已經完成大致上所有的功能了,今天篇稍微調整一下 UI 畫面,並讓我們的選單有上下頁的功能。

https://media.giphy.com/media/TsV9Sr9AG2Ne8/giphy.gif

我們已知回傳資料內有上下頁完整的 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 當範本介紹一下有關的用法!


上一篇
Redux 深入淺出 - [ Day 23 ] React Redux 非同步處理
下一篇
Redux 深入淺出 - [ Day 25 ] Redux Toolkit Query 簡介
系列文
30天深入淺出Redux31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言