iT邦幫忙

2022 iThome 鐵人賽

DAY 13
0
自我挑戰組

我與 React 的 30天系列 第 13

Day 13用 useEffect 獲取不同的資料(下)

  • 分享至 

  • xImage
  •  

昨天我們說明了在網頁中用 AJAX 的方式去請求資料,並且加上 useEffect 以及說明為什麼要加上 useEffect,的好處,以及解決了什麼問題,今天就讓我們繼續看看 useEffect 還有什麼用法吧,

改變我們的 url

昨天我們演示了剛來到我們的頁面會用 AJAX 的方式拿到一些 user 的資料,今天我們的目標就是,每當我們切換按鈕就會獲得不同的資料,所以讓我們開始吧

import React, { useState, useEffect } from "react";
import Axios from "axios";
import "./fetchData.css";

const FetchData = () => {
  const [list, setList] = useState([]);

  useEffect(() => {
    Axios({ url: 'https://jsonplaceholder.typicode.com/post' })
      .then(response => {
        setList(response.data);
        console.log("成功獲得資料");
      })
      .catch(error => {
        console.log(error);
      });
  }, []);

  return (
    <>
      <div className="buttonContainer">
        <button className="customButton">貼文 (post)</button>
        <button className="customButton">代辦事項 (todo)</button>
        <button className="customButton">相簿清單 (album)</button>
      </div>

      <div className="listStyle">
        <div className="listContainer">
          {list.map(item => (
            <div className="listItem" key={item.id}>
              <h3>{item.id}</h3>
              <h3>標題:{item.title}</h3>
            </div>
          ))}
        </div>
      </div>
    </>
  );
}

export default FetchData;

這是我們昨天得樣子,加上了三顆按鈕,希望可以就由這三顆按鈕來切換,使我的網頁獲得不同的內容

我想聰明的你應該知道,如果我們要重新使這這個 Component 再次 render 的話,我們可以用 useState 去告訴 React 我們的狀態改變了,來重新渲染我們的畫面吧

所以我們在這位這個組件加上這句

const [type, setType] = useState('posts')

並在 Axios 中改變我們的 url

Axios({ url: `https://jsonplaceholder.typicode.com/${type}` })

這樣就算完成初步的設置了

useEffect 我要拿到不同資料

現在就讓我們用 useState 來改變我們的type 變數吧

我們在 Component 中加上這些

const postHandler = () => {setType('posts')}
const todoHandler = () => {setType('todos')}
const albumHandler = () => {setType('albums')}

並且將這些 function 掛到我們的 button 上面

<div className="buttonContainer">
  <button className="customButton" onClick={postHandler}>貼文 (post)</button>
  <button className="customButton" onClick={todoHandler}>代辦事項 (todo)</button>
  <button className="customButton" onClick={albumHandler} >相簿清單 (album)</button>
</div>

然後最重要的一點就是我們的 useEffect 的 第二個參數 dependency 需要去監聽 type 的改變,才會去執行

所以我們將 useEffect 改成這樣

useEffect(() => {
  Axios({ url: `https://jsonplaceholder.typicode.com/${type}` })
    .then(response => {
      setList(response.data);
      console.log("成功獲得資料");
    })
    .catch(error => {
      console.log(error);
    });
  return (
    console.log("Clean UP")
  ) 
}, [type]);

這樣我們每次點選不同按鈕時,我們的內容都會改變~

有注意到嗎,我們在 useEffect 中寫了這段

  return (
    console.log("Clean UP")
  ) 

其實這一個 return 是可加可不加的,若有加的話在每次使用 useEffect 的話,會先執行 return 中的內容像是這樣

那可以用在什麼地方呢,這邊舉個簡單的例子

  const [count, setCount] = useState(0)

  useEffect(() => {
    Axios({ url: `https://jsonplaceholder.typicode.com/${type}` })
      .then(response => {
        setList(response.data);
        setCount(prevCount => prevCount + 1)
        console.log("成功獲得資料");
        console.log(count);
      })
      .catch(error => {
        console.log(error);
      });
  }, [type]);

我在這裡加上 新的 useState 並在每次進入 useEffect 中讓他的值加一
會得到這樣

但是我們只是想要每次 進入useEffect 才讓他從 0 變成 1 ,而不是每次
獲取資料時都讓他的值增加,因為這樣會不斷累加,不是我們想要的效果

這時我們在 useEffect 中就會使用 return

  const cleanUp = () => {
    setCount(0)
    console.log("cleanUp");
  }
  
    useEffect(() => {
    Axios({ url: `https://jsonplaceholder.typicode.com/${type}` })
      .then(response => {
        setList(response.data);
        setCount(prevCount => prevCount + 1)
        console.log("成功獲得資料");
        console.log(count);
      })
      .catch(error => {
        console.log(error);
      });
      return (
        cleanUp()
      )
  }, [type]);

這樣我們執行得結果就會變成這樣

小結

今天介紹了 useState 和 useEffect 的組合技,也說明了 useEffect 中是可以使用 return 以及他的目的

明天將會繼續探討 react 的世界,感謝大家~


上一篇
Day 12 用 useEffect 獲取不同的資料(上)
下一篇
Day 14 props 我不要你了? 讓我們來試試 useContext
系列文
我與 React 的 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言