iT邦幫忙

2022 iThome 鐵人賽

DAY 12
0
自我挑戰組

我與 React 的 30天系列 第 12

Day 12 用 useEffect 獲取不同的資料(上)

  • 分享至 

  • xImage
  •  

昨天我們介紹了 useEffect 的觸發時機,根據 useEffect 第二個參數 [dependency] 的不同會有不同的觸發時機,今天我們就來看看 useEffect 實際可以運用在哪種情形

使用 useEffect 去獲取資料

想像一下我們在瀏覽網頁的時候,像是 youtube 的時候,一進入首頁的會給你許多推薦的影片,但這時發現這些影片中,沒有我喜歡的影片,那我們可能會去選擇搜尋關鍵字,或是點擊旁邊的 silebar 去選擇我們喜歡的種類,這網站就會依照我們的要求去獲得不同的資料,最後顯示在畫面,那這跟 useEffect 有關係嗎 ? 還記得 useEffect的觸發時機嗎,初次渲然會觸發執行,再來就要看 第二個參數 [dependency] 給予的條件了,他就很像監聽器會監聽這個 array 的數值有沒有變動

讓我們使用這個網站為例 (https://jsonplaceholder.typicode.com/)

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/users` })
      .then(response => {
        setList(response.data);
      })
      .catch(error => {
        console.log(error);
      });
  }, []);

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

export default FetchData;

這樣在我的 React 初次 render 畫面的時候,就會執行 useEffect,並且只會執行一次

幹嘛用你啊 useEffect

那你會認為說我可以不要用 useEffect,我直接讓 function 去打 API 就好了,反正我只要 setList(response.data) 成功之後。
我的 list 就不會改變了啊,這樣也不會執行過多的渲染,

但是夢想總是美好的~

讓我們看看這樣做會發生什麼事,我們將 useEffect 拔掉變成這樣

  Axios({ url: `https://jsonplaceholder.typicode.com/users` })
  .then(response => {
    setList(response.data);
    console.log("成功獲得資料");
  })
  .catch(error => {
    console.error(error);
  });

會發現出大事了!怎麼出現無窮迴圈了

Call by value ? or Call by reference ?

那就讓我來用這個例子來說明,我們就會清楚發生什麼事了!

因為 React useState 中,我們使用 setState 會比較 oldvalue 跟 newvalue 用(===)比較,也就是說比較 舊值 跟 新值 若兩個有不同就重新執行這個 Component, 但是用從上圖可以看到 a 跟 b ,兩個不是一樣嗎?

你只能說他們看起來一樣~
在 JavaScript 的世界中,字串、數字、布林值,都是 Call by value
但是 陣列,物件,function 都是 Call by reference,也就是會去比較他們記憶體位址的不同,所以雖然看起來是一樣的,實際上記憶體位址是不同的,所以若沒有用 useEffect 去執行,fetch API 的話每次 setList時其實都是不同的,因為在 array陣列中 React 會去比較 reference 的是否有不同,所以若是每次都不同的話,就會重新渲染畫面,
所以才會造成無限迴圈,所以就讓我們乖乖地使用 useEffect 吧!

小結

今天說明了我們在打 API 時為什麼要使用 useEffect,他的目的為何,又能幫我們解決什麼事,明天將會接續下去我們該如何在同一個頁面會去不同資料


上一篇
Day 11 useEffect 我來了
下一篇
Day 13用 useEffect 獲取不同的資料(下)
系列文
我與 React 的 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言