React Native v2 - Hooks and Network Requests

前言

最近要轉換跑道學習開發 React Native,學習的課程是 Kadi Kraman 的 React Native v2 ,寫這篇筆記的時候是學習 React Native 的第三天,這個章節的前半部在講 Hook,算是我相對熟悉的區塊,看到熟人總是有點感動。

初學 React Native,概念上應該會有不少錯誤,如果有誤的話也麻煩不吝指正,非常感謝!

useState, useCallback, useEffect

useState, useCallback, useEffect

這章節就是在介紹這三個 hook 如何使用,就不多做介紹。

Network Requests Exercise 📝

Network Requests Exercise

Update your application to fetch the color palettes from the following url: https://color-palette-api.kadikraman.now.sh/palettes

Hint: you should use useEffect, useCallback and useState for this!

這邊如果平常有在寫 React 的人應該很快就能完成,所以就不多做贅述。

Home.tsx

export default function Home({ navigation }: TProps) {
  const [colorPalettes, setColorPalettes] = useState([]);

  const fetchColorPalettes = useCallback(async () => {
    const result = await fetch(
      'https://color-palette-api.kadikraman.now.sh/palettes',
    );

    if (result.ok) {
      const colors = await result.json();
      setColorPalettes(colors);
    }

    return result;
  }, []);

  const renderPalettePreview = ({ item }: { item: TPalette }) => {
    return (
      <PalettePreview
        handlePress={() => navigation.navigate('ColorPalette', item)}
        colorPalette={item}
      />
    );
  };

  useEffect(() => {
    fetchColorPalettes();
  }, [fetchColorPalettes]);

  return (
    <FlatList
      style={styles.container}
      data={colorPalettes}
      renderItem={renderPalettePreview}
      keyExtractor={(item) => item.paletteName}
    />
  );
}

Pull to refresh

Pull to refresh

這章節主要講的是使用 App 的時候,我們有個很直覺的更新資料方式是把手機往下滑,這時候通常會出現 loading 圖示把資料做更新,我們要做的事情就是這個。

FlatList 裡面,可以透過 refreshingonRefresh 來辦到,首先我們要做的事情就是新增 onRrefresh 用的 function:

const [isRefreshing, setIsRefreshing] = useState(false); // 上面先宣告 state

const handleRefresh = async () => {
	setIsRefreshing(true);
  await fetchColorPalettes();

  setTimeout(() => {
    setIsRefreshing(false);
  }, 1000);
};


/* FlatList 這樣寫 */ 
<FlatList
  style={styles.container}
  data={colorPalettes}
  renderItem={renderPalettePreview}
  keyExtractor={(item) => item.paletteName}
  refreshing={isRefreshing}
  onRefresh={handleRefresh}
/>

步驟也很單純,就是四件事:

  1. 宣告 isRefreshing state 和 setIsRefreshing
  2. 宣告 handleRefresh 的 function,先把 setIsRefreshing 設置為 true
  3. await fetchColorPalettes 執行完成
  4. setIsRefreshing 將 state 改為 false

另外會注意到,第 4 個步驟做了 setTimeout 的事情,原因是有時候 data fetch 太快,loading 圖示甚至來不及跑完,為了讓使用者感受到「App 有在更新資料」,為了 UX 體驗才會設置 1 秒的 loading 時間,看起來很反直覺,因為我們在做的是讓 App 變慢的事情,但又有點道理。

客製化的 RefreshIcon

剛剛提到 FlatList 裡面,可以透過 refreshingonRefresh 來處理 refresh,不過目前 refresh 的 icon 都是系統內建的樣式,有時候自己的 App 會想要有客製化的 refreshIcon,就可以透過 RefreshControl 來辦到這件事情。

延續上面 FlatList 的 code,並且做點小改動:

 <FlatList
   style={styles.container}
   data={colorPalettes}
   renderItem={renderPalettePreview}
   keyExtractor={(item) => item.paletteName}
   refreshControl={
   	<RefreshControl refreshing={isRefreshing} onRefresh={handleRefresh} />
   }
/>

References

React Native, v2