[TIL] 0627 | React with Redux, Next.js, TypeScript

Teasanยท2022๋…„ 6์›” 29์ผ
0

TIL

๋ชฉ๋ก ๋ณด๊ธฐ
19/36
post-thumbnail

๋ชฉ์ฐจ

  • Meals ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐฑ์—”๋“œ๋กœ ์ด๋™ํ•˜๊ธฐ
  • Http๋ฅผ ํ†ตํ•ด Meal ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ

โœง Meals ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐฑ์—”๋“œ๋กœ ์ด๋™ํ•˜๊ธฐ

Firebase Realtime Database

  • AvailableMeals.js ํŒŒ์ผ ๋‚ด๋ถ€์— ์žˆ๋˜ ๋”๋ฏธ ๋ฐ์ดํ„ฐ DUMMY_MEALS ๋ฅผ Firebase Realtime Database ์— ์ˆ˜๊ธฐ๋กœ ์ž‘์„ฑํ•˜์—ฌ ์˜ฎ๊ธด๋‹ค.

Http๋ฅผ ํ†ตํ•ด Meal ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ

const [meals, setMeals] = useState([]);

useEffect(() => {
  const fetchMaels = async () => {
    const response = await fetch(
      "https://react-http2-xxxxxxxxx/meals.json"
    ).then();

    const responseData = await response.json();

    // ๊ฐ์ฒด๋กœ ๋ฐ›์•„์˜ค๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฐ์—ดํ™” ์‹œ์ผœ์•ผ ํ•จ.
    const loadedMeals = [];

    for (const key in responseData) {
      loadedMeals.push({
        id: key,
        name: responseData[key].name,
        description: responseData[key].description,
        price: responseData[key].price,
      });
    }

    setMeals(loadedMeals);
  };

  fetchMaels();
}, []);
  • fetch() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ API๋ฅผ ์—ฐ๊ฒฐํ•˜๊ณ  http ์š”์ฒญ์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋Š” ๋กœ์ง์ด๋‹ค.
fetch();
  • ๋จผ์ € fetch() ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜๋˜, useEffect() ํ›… ์•ˆ์— ๋„ฃ์–ด์ฃผ์ž. ์ตœ์ดˆ 1ํšŒ ์ดํ›„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒˆ๋กœ ๋ฐ›์•„์˜ฌ ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์—, ์˜์กด์„ฑ ๋ฐฐ์—ด์€ ๋นˆ ๋ฐฐ์—ด๋กœ ๋‚จ๊ฒจ์ค€๋‹ค.
useEffect(() => {
  fetch();
}, []);
  • Firbase Realtime database ์— ์šฐ๋ฆฌ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์•„๋‘” ํ”„๋กœ์ ํŠธ์˜ ๋งํฌ์— "meals" ๋กœ ์ ‘๊ทผํ•˜์—ฌ ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. ์ฃผ์†Œ ๋์—๋Š” .json์„ ๋ถ™์—ฌ์ค˜์•ผ ํ•˜๋Š”๋ฐ, ์ด๋Š” ํŒŒ์ด์–ด๋ฒ ์ด์Šค์—์„œ ์š”๊ตฌํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ ‘๊ทผํ•˜๊ณ  ์‹ถ์€ ๋ฐ์ดํ„ฐ ์ด๋ฆ„ ๋’ค์— ๋ถ™์ด๋ฉด ๋œ๋‹ค.
useEffect(() => {
  fetch("https://react-http2-xxxxxxxxx/meals.json");
}, []);
  • ๋‹ค์Œ์œผ๋กœ๋Š” ํŒŒ์ด์–ด๋ฒ ์ด์Šค๊ฐ€ ์ด๊ณณ์—์„œ ๋…ธ์ถœํ•œ REST API ์—”๋“œํฌ์ธํŠธ๋กœ ์š”์ฒญ์„ ๋ณด๋‚ผ ๊ฒƒ์ด๋‹ค. ์ด ์š”์ฒญ์„ ํ†ตํ•ด์„œ meals ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•œ๋‹ค. ์•ž์„œ fetch ๋ฅผ ํ†ตํ•œ HTTP ์š”์ฒญ์—์„œ ๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ HTTP ๋ฉ”์†Œ๋“œ ๋“ฑ์„ ๋ณ€๊ฒฝํ•˜์—ฌ ์š”์ฒญ์„ ๋ณด๋‚ผ ์ˆ˜๋„ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ํ˜„์žฌ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์˜ค๊ธฐ๋งŒ ํ•˜๋ฉด ๋˜๊ณ , fetch ํ•จ์ˆ˜์˜ ๋””ํ†จํŠธ๋Š” "GET" ์ด๊ธฐ ๋•Œ๋ฌธ์—, ๊ตณ์ด ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ํ•„์š”๊ฐ€ ์—†์„ ๊ฒƒ์ด๋‹ค.
useEffect(() => {
  fetch("https://react-http2-xxxxxxxxx/meals.json");
}, []).then();
  • ์ด์ œ fetch๋Š” promise๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. HTTP ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๊ฒƒ์€ ๋น„๋™๊ธฐ ํ…Œ์Šคํฌ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋’ค์— .then() ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. ์ด then() ํ•จ์ˆ˜๋Š” ์‘๋‹ต์„ ๋ฐ›์œผ๋ฉด ์š”์ฒญ์ด ์ด๋ฃจ์–ด์งˆ ๋•Œ ํŠธ๋ฆฌ๊ฑฐ๊ฐ€ ๋œ๋‹ค. ์—๋Ÿฌ๋ฅผ ํ•ธ๋“ค๋งํ•˜๊ฑฐ๋‚˜ ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•œ๋‹ค.
useEffect(async () => {
  await fetch("https://react-http2-xxxxxxxxx.firebaseio.com/meals.json").then();
}, []);
  • async/await ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๋ฐ ๊ทธ ์ด์œ ๋Š” useEffect()๋กœ ์ž…๋ ฅํ•œ ํ•จ์ˆ˜์—์„œ๋Š” promise๋กœ ๋ฐ˜ํ™˜ํ•ด์„œ๋Š” ์•ˆ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์•ž์„œ ํ•™์Šตํ–ˆ๋˜ ๋‚ด์šฉ์ฒ˜๋Ÿผ useEffect์— ์ž…๋ ฅํ•œ ํ•จ์ˆ˜๋Š” ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ cleanup ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ• ์ง€๋„ ๋ชจ๋ฅด๊ณ , ์ด๋Š” cleanup ํ•จ์ˆ˜๊ฐ€ ๋™์‹œ์— ์‹คํ–‰๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ๋œป์ด๊ธฐ๋„ ํ•˜๋‹ค. ์ฆ‰, promise ๋‚˜ async/await ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด cleanup์„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋”ฐ๋ผ์„œ useEffect์— ์ž…๋ ฅํ•œ ํ˜„์žฌ์˜ ์ด ํ•จ์ˆ˜๋Š” async ํ•จ์ˆ˜๋กœ ๋ณ€๊ฒฝํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค. ํ•˜์ง€๋งŒ useEffect ๋Œ€์‹  async/await ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ์ด๋Ÿฐ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
useEffect(() => {
  const fetchMeals = async () => {
    await fetch("https://react-http2-xxxxxxxxx.firebaseio.com/meals.json");
  };

  fetchMeals();
}, []);
  • ์ƒˆ๋กœ์šด ํ•จ์ˆ˜(fetchMeals)๋ฅผ ๋งŒ๋“ค๊ณ  ์ด ์•ˆ์—์„œ async/await ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ์ ์œผ๋กœ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ ‡๊ฒŒ ๋˜๋ฉด .then()์€ ํ•„์š”๊ฐ€ ์—†์œผ๋‹ˆ ์ด ๋ถ€๋ถ„์€ ์‚ญ์ œํ•ด์ค€๋‹ค. ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์„ ํ†ตํ•ด์„œ ํ•ด๋‹น ํ•จ์ˆ˜๋Š” ์—ฌ์ „ํžˆ ์‹คํ–‰๋˜๊ณ , useEffect ํ•จ์ˆ˜ ์ „์ฒด์—์„œ๋Š” ์ด์ œ promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๊ณ ์„œ๋„ ์šฐ๋ฆฌ๋Š” async/await ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. ์ด๊ฒƒ์€ ๋ชจ๋‘ ์•ฝ๊ฐ„์˜ ํšŒํ”ผ?๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ๋งํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.
useEffect(() => {
  const fetchMeals = async () => {
    const response = await fetch(
      "https://react-http2-xxxxxxxxx.firebaseio.com/meals.json"
    );
  };

  fetchMeals();
}, []);
  • ๊ทธ ๋‹ค์Œ์—๋Š” fetchMeals ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ fetch() ๋กœ ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ๋ฅผ response ๋ณ€์ˆ˜ ์•ˆ์— ๋„ฃ์–ด์ค€๋‹ค.
useEffect(() => {
  const fetchMeals = async () => {
    const response = await fetch(
      "https://react-http2-xxxxxxxxx.firebaseio.com/meals.json"
    );
    const responseData = await response.json();
  };

  fetchMeals();
}, []);
  • response ๋ฅผ json()์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ , ๊ทธ๊ฒƒ์„ responseData ๋ณ€์ˆ˜์— ํ• ๋‹นํ•œ๋‹ค. ์ด ์—ญ์‹œ fetchMeals ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— await๋ฅผ ๋ถ™์—ฌ์ค€๋‹ค.

  • ์ด์ œ ํŒŒ์ด์–ด๋ฒ ์ด์Šค์—์„œ ์–ป์€ responseData๋Š” ํŒŒ์ด์–ด๋ฒ ์ด์Šค์— ํŠน์ •๋˜์–ด ์žˆ์œผ๋ฉฐ, ํ•ญ์ƒ ์ด๋Ÿฌํ•œ id๊ฐ€ ์žˆ๋Š” ๊ฐ์ฒด๊ฐ€ ๋  ๊ฒƒ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  "m1, m2, m3, m4"๊ฐ€ key ๊ฐ€ ๋˜๊ณ , ํ‚ค์— ๋Œ€ํ•œ ๊ฐ’์€

  • ์ด๋Ÿฌํ•œ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง„ ์ค‘์ฒฉ ๊ฐ์ฒด๊ฐ€ ๋œ๋‹ค. ์ฝ”๋“œ๋กœ ๋‹ค์‹œ ๋Œ์•„๊ฐ€๋ณด์ž.
useEffect(() => {
  const fetchMeals = async () => {
    const response = await fetch(
      "https://react-http2-xxxxxxxxx.firebaseio.com/meals.json"
    );
    const responseData = await response.json();
  };

  fetchMeals();
}, []);
  • ์šฐ๋ฆฌ๋Š” ํ˜„์žฌ responseData ๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๊ฐ€ ์•„๋ž˜์˜ ์ฝ”๋“œ๋“ค์„ ํ™•์ธํ•ด๋ดค์„ ๋•Œ ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ ๋ฐฐ์—ด์ด ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜ํ•  ํ•„์š”์„ฑ์ด ์žˆ๋‹ค.
// ๋ฐฐ์—ด์˜ ํ˜•ํƒœ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์•ผ ํ•œ๋‹ค.
const mealsList = DUMMY_MEALS.map((item) => (
  <MealItem
    key={item.id}
    id={item.id}
    name={item.name}
    description={item.description}
    price={item.price}
  />
));
  • ๋จผ์ €, loadedMeals ๋ผ๋Š” ์ด๋ฆ„์˜ ๋นˆ ๋ฐฐ์—ด ์ƒ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๊ณ ,
useEffect(() => {
  const fetchMeals = async () => {
    const response = await fetch(
      "https://react-http2-xxxxxxxxx.firebaseio.com/meals.json"
    );
    const responseData = await response.json();

    const loadedMeals = [];
  };

  fetchMeals();
}, []);
  • for in ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•ด์„œ responseData ์ฆ‰, responseData ๊ฐ์ฒด์˜ ๋ชจ๋“  ํ‚ค๋ฅผ ๋ฐ˜๋ณตํ•˜์—ฌ loadedMeals ๋ฐฐ์—ด ์•ˆ์— ๋„ฃ์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
useEffect(() => {
  const fetchMeals = async () => {
    const response = await fetch(
      "https://react-http2-xxxxxxxxx.firebaseio.com/meals.json"
    );
    const responseData = await response.json();

    const loadedMeals = [];

    for (const key in responseData) {
      loadedMeals.push();
    }
  };

  fetchMeals();
}, []);
  • key๋Š” ์•ž์—์„œ ์–˜๊ธฐํ•œ ๋Œ€๋กœ ํŒŒ์ด์–ด๋ฒ ์ด์Šค์˜ "meals"์ด๋ž€ ์ด๋ฆ„์˜ ๋ฐ์ดํ„ฐ ๋‚ด๋ถ€์˜ id๋ฅผ ๊ฐ€๋ฅดํ‚จ๋‹ค.

  • ๊ทธ๋ฆฌ๊ณ  ํ‚ค์˜ ๊ฐ’์€ ์ค‘์ฒฉ ๊ฐ์ฒด๊ฐ€ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๊ณณ์—์„œ loadedMeals๋ฅผ ์ด์šฉํ•ด ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ฒ˜์Œ์— ๋น„์–ด์žˆ๋˜ ๋ฐฐ์—ด์— ๋ฐ€์–ด ๋„ฃ์„ ๊ฒƒ์ด๋‹ค.
for (const key in responseData) {
  loadedMeals.push({});
}
  • ์šฐ๋ฆฌ๊ฐ€ ๊ฐ์ฒด ์•ˆ์— id๋ฅผ ์ƒ์ •ํ•˜๋Š” ๊ฒƒ์€ meals๊ฐ€ id ํ•„๋“œ๋ฅผ ๊ฐ€์ง„๋‹ค๊ณ  ์˜ˆ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
const mealsList = DUMMY_MEALS.map((item) => (
  <MealItem
    key={item.id}
    //
    id={item.id}
    //
    name={item.name}
    description={item.description}
    price={item.price}
  />
));
  • ๋”ฐ๋ผ์„œ ๋กœ๋”ฉ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€ํ™˜ํ•˜์—ฌ id ํ•„๋“œ๋ฅผ ๊ฐ–๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค.
for (const key in responseData) {
  loadedMeals.push({
    id: key,
  });
}
  • id๋Š” key๋กœ ๊ฐ’์„ ์„ค์ •ํ•˜๋Š”๋ฐ, ์ด๋Š” ์•ž์„œ ๋งํ–ˆ๋‹ค์‹œํ”ผ key๋Š” ์šฐ๋ฆฌ๊ฐ€ ๊ฐ€์ง€๊ณ  ์˜ค๋Š” ๊ฐœ๋ณ„ meal์˜ id๊ฐ€ ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด์ œ ๋‚˜๋จธ์ง€ name, description, price ํ•„๋“œ๋ฅผ ๋งˆ์ € ์ž‘์„ฑํ•ด๋ณด์ž. ์ฃผ์–ด์ง„ ๋ฐ์ดํ„ฐ์ธ responseData์—์„œ for in ์œผ๋กœ ๋Œ๋ฉด์„œ ๊ฐ๊ฐ์˜ ํ•„๋“œ ์†์„ฑ์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.
for (const key in responseData) {
  loadedMeals.push({
    id: key,
    name: responseData[key].name,
    description: responseData[key].description,
    price: responseData[key].price,
  });
}
  • ์ด์ œ ๊ฐ€์ ธ์™€์„œ ๋ณ€ํ™˜ํ•œ ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด์ธ loadedMeals ๋ฅผ ๋‚˜๋จธ์ง€ ์ปดํฌ๋„ŒํŠธ์— ๋…ธ์ถœํ•ด์•ผ๋งŒ ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฐ€์ ธ์˜ค๊ธฐ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•ด์•ผ ํ•œ๋‹ค. ์ด๊ฒƒ์€ ๋น„๋™๊ธฐ ํ…Œ์Šคํฌ๋กœ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ์œผ๋กœ ๋กœ๋”ฉ๋œ ํ›„์—๋งŒ ์‹œ์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ฒ˜์Œ์—๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์œผ๋ฉฐ, ๋ฐ์ดํ„ฐ๊ฐ€ ๊ทธ๊ณณ์— ์žˆ์„ ๊ฒฝ์šฐ์— ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•œ๋‹ค. ๋˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜๊ณ , ๋˜ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์ฒด๊ฐ€ ๋‹ค์‹œ ์—…๋ฐ์ดํŠธ๋˜์–ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ๊ณ ๋ คํ•ด์„œ ์ด๋ฅผ ์œ„ํ•œ ์ƒํƒœ(state)๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋Š” ๊ฑธ ์ถ”์ธกํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.
const [meals, setMeals] = useState([]);
  • ์ฒ˜์Œ์—๋Š” ๋นˆ ๋ฐฐ์—ด์„ ์ดˆ๊ธฐ๊ฐ’์œผ๋กœ ๋‘”๋‹ค. ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๊ธฐ ์ „์— ๋นˆ ๋ฐฐ์—ด๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋น„๋ก ์ฒ˜์Œ์€ ๋นˆ ๋ฐฐ์—ด์ด์ง€๋งŒ ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋”ฉ๋˜๋ฉด meals ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋  ๊ฒƒ์ด๋‹ค.
const mealsList = meals.map((item) => (
  <MealItem
    key={item.id}
    id={item.id}
    name={item.name}
    description={item.description}
    price={item.price}
  />
));
  • ์ด์ œ ์•„๋ž˜์˜ mealsList ์ปดํฌ๋„ŒํŠธ์—์„œ DUMMY_MEALS ๋กœ ๋งคํ•‘ํ•ด์ฃผ๋˜ ๊ฒƒ์„ meals ์ƒํƒœ(state)๋กœ ์ˆ˜์ •ํ•ด์ค€๋‹ค. ์ด๋„ ์ฒ˜์Œ์—๋Š” ๋นˆ ๋ฐฐ์—ด์ด์ง€๋งŒ ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋”ฉ๋˜๋ฉด ๋ณ€๊ฒฝ๋  ๊ฒƒ์ด๋‹ค.
useEffect(() => {
  const fetchMeals = async () => {
    const response = await fetch(
      "https://react-http2-xxxxxxxxx.firebaseio.com/meals.json"
    );
    const responseData = await response.json();

    const loadedMeals = [];

    for (const key in responseData) {
      loadedMeals.push();
    }

    setMeals(loadedMeals);
  };

  fetchMeals();
}, []);
  • ๋”ฐ๋ผ์„œ for in ๋ฐ˜๋ณต๋ฌธ ์ดํ›„์— ๋ณ€ํ™˜๋œ loadedMeals ๋ฐ์ดํ„ฐ๋ฅผ meals ์—…๋ฐ์ดํŠธ ํ•จ์ˆ˜์ธ setMeals์— ๋„ฃ์–ด์ค€๋‹ค. ์ด์ œ ์ปดํฌ๋„ŒํŠธ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋  ๊ฒƒ์ด๋‹ค.

์ •๋ฆฌ

  • ๋น„์–ด์žˆ๋Š” ์˜์กด์„ฑ ๋ฐฐ์—ด์ด ์‹ ๊ฒฝ ์“ฐ์ผํ…Œ์ง€๋งŒ, ํ˜„์žฌ useEffect ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์‹คํ–‰๋˜๋Š” ๋กœ์ง๋“ค์€ ์ „๋ถ€ ์˜์กด์„ฑ์ด ์—†๊ณ , ์™ธ๋ถ€ ์ปดํฌ๋„ŒํŠธ์— ํŠน์ •๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์“ฐ๊ณ  ์žˆ์ง€๋„ ์•Š์œผ๋‹ˆ, ์ฒ˜์Œ ๋กœ๋”ฉ ๋  ๋•Œ๋งŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋„๋ก ์ฆ‰ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋นˆ ๋ฐฐ์—ด๋กœ ๋‘๋Š” ๊ฒƒ์ด ๋งž๊ธฐ์— ๊ฑฑ์ •ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๋Š” ๊ฑธ ๊ธฐ์–ตํ•˜์ž.

โœฆ ์ถœ์ฒ˜


๐Ÿšจ ํ•ด๋‹น ํฌ์ŠคํŒ…์€ Udemy์˜ โŒœReact ์™„๋ฒฝ ๊ฐ€์ด๋“œโŒŸ ๊ฐ•์˜๋ฅผ ๋ฒ ์ด์Šค๋กœ ํ•œ ๊ธฐ๋ก์ž…๋‹ˆ๋‹ค.
โœ๐Ÿป ๊ฐ•์˜ git repo ๋ฐ”๋กœ๊ฐ€๊ธฐ

profile
์ผ๋‹จ ๊ณต๋ถ€๊ฐ€ '์ ์„ฑ'์— ๋งž๋Š” ๊ฐœ๋ฐœ์ž. ๊ทผ์„ฑ์žˆ์Šต๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€