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 📝
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
anduseState
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
這章節主要講的是使用 App 的時候,我們有個很直覺的更新資料方式是把手機往下滑,這時候通常會出現 loading 圖示把資料做更新,我們要做的事情就是這個。
在 FlatList
裡面,可以透過 refreshing
和 onRefresh
來辦到,首先我們要做的事情就是新增 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}
/>
步驟也很單純,就是四件事:
- 宣告
isRefreshing
state 和setIsRefreshing
- 宣告
handleRefresh
的 function,先把setIsRefreshing
設置為 true - await
fetchColorPalettes
執行完成 setIsRefreshing
將 state 改為 false
另外會注意到,第 4 個步驟做了 setTimeout
的事情,原因是有時候 data fetch 太快,loading 圖示甚至來不及跑完,為了讓使用者感受到「App 有在更新資料」,為了 UX 體驗才會設置 1 秒的 loading 時間,看起來很反直覺,因為我們在做的是讓 App 變慢的事情,但又有點道理。
客製化的 RefreshIcon
剛剛提到 FlatList
裡面,可以透過 refreshing
和 onRefresh
來處理 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} />
}
/>