這章節將透過 firebase 所提供的簡易資料庫與 API 來實際在 React 專案中串接應用
一筆簡單的陣列資料,並透過這筆資料產生 JSX,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| const AvailableMeals = () => { const meals = [...];
const mealsList = meals.map((meal) => ( <MealItem key={meals.id} id={meals.id} name={meal.name} description={meal.description} price={meal.price} /> ));
return ( <section className={classes.meals}> <Card> <ul>{mealsList}</ul> </Card> </section> ); };
|
Fetching Data
在串接 firebase 所提供的 API 時,需使用 http 或是 在 url 最後方加上 .json,否則會出現 CORS error,而因為 http request 是一個 async event,所以須透過 State 來存取資料 ; 而像是這種在頁面載入時,就會自動送出 request 取得資料的情況,就可以使用 useEffect()
,並使 dependency array 為 empty array,這麼一來就只有在 component first render 時會觸發
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const [meals, setMeals] = useState([]);
useEffect(async () => { const response = await fetch( "https://react-http-77951-default-rtdb.firebaseio.com/meals.json" ); const data = await response.json(); const loadedMeals = [];
for (const key in data) { loadedMeals.push({ id: key, name: data[key].name, description: data[key].description, price: data[key].price, }); }
setMeals(loadedMeals); }, []);
|
但這裡要特別注意的是,useEffect()
的 callback function 只能是一個 sync funcion,如果要在其中做到 async event,就必須透過另一層 async function 來封裝
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| const [meals, setMeals] = useState([]);
useEffect(() => { const fetchMeals = () => { const response = await fetch( "https://react-http-77951-default-rtdb.firebaseio.com/meals.json" ); const data = await response.json(); const loadedMeals = [];
for (const key in data) { loadedMeals.push({ id: key, name: data[key].name, description: data[key].description, price: data[key].price, }); }
setMeals(loadedMeals); }
fetchMeals(); }, []);
|
而如果這個 async function 其實只有在 useEffect()
中呼叫一次,也可以改寫成 IIFE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| useEffect(() => { (async () => { const response = await fetch( "https://react-http-77951-default-rtdb.firebaseio.com/meals.json" ); const data = await response.json(); const loadedMeals = [];
for (const key in data) { loadedMeals.push({ id: key, name: data[key].name, description: data[key].description, price: data[key].price, }); }
setMeals(loadedMeals); })(); }, []);
|
資料參考
React - The Complete Guide (Incl Hooks, React Router, Redux)