useEffect

유석현(SeokHyun Yu)·2022년 11월 20일
0

React

목록 보기
7/21
post-thumbnail

index.js

import React from "react";
import ReactDOM from "react-dom/client";
import AppProducts from "./AppProducts";
import "./index.css";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <AppProducts />
  </React.StrictMode>
);

AppProduct.jsx

import React from "react";
import { useState } from "react";
import Product from "./components/Product";

export default function AppProducts() {
  const [showProducts, setShowProducts] = useState(true);

  return (
    <div>
      {showProducts && <Product />}
      <button
        onClick={() => {
          setShowProducts((show) => !show);
        }}
      >
        Toggle
      </button>
    </div>
  );
}

Product.jsx

import React from "react";
import { useEffect } from "react";
import { useState } from "react";

export default function Product() {
  const [products, setProducts] = useState([]);
  const [checked, setChecked] = useState(false);
  const handleChange = () => {
    setChecked((prev) => !prev);
  };

  // 컴포넌트 안에 state가 변경되면 그 컴포넌트를 다시 호출하는데
  // fetch로 데이터를 불러와서 setProducts로 products의 상태를 업데이트 해주는 것까지는 좋지만
  // 상태가 바뀌었으니 Product 컴포넌트가 또 호출되고 데이터를 fetch해오고 setProducts로 상태를 업데이트하고 상태가 바뀌었으니 또 Product를 호출하면서 무한루프가 발생한다
  // 이때 useEffect() 훅을 사용한다
  //   fetch("data/products.json")
  //     .then((res) => res.json())
  //     .then((data) => {
  //       console.log(data);
  //       setProducts(data);
  //     })
  //     .catch((e) => {
  //       console.log(e);
  //     });

  useEffect(() => {
    fetch(`data/${checked ? "sale_" : ""}products.json`)
      .then((res) => res.json())
      .then((data) => {
        console.log(data);
        setProducts(data);
      })
      .catch((e) => {
        console.log(e);
      });

    // 콜백에서 실행할 로직을 다 끝내고 실행할 함수 등록
    // 다음 useEffect를 실행하기 직전, 혹은 언마운트 시에 실행된다
    return () => {
      console.log("clear!");
    };

    // 2번째 인자로 넘겨주는 배열의 값들 중 하나라도 state가 바뀌면 useEffect에 콜백으로 등록된 함수를 실행한다
    // 빈 배열을 넣어주면 state변화를 감지하지 않겠다는 뜻이므로 Product 컴포넌트가 호출될 때 한번만 실행된다
  }, [checked]);

  return (
    <div>
      <input id="checkbox" type="checkbox" onChange={handleChange} />
      <label htmlFor="checkbox">SALE</label>
      <ul>
        {/* 배열을 map으로 돌려서 리턴해줄때 li 요소 안에 key 속성을 무조건 넣어줘야 한다 */}
        {/* 보통 배열안에 담긴 id 값을 넣곤 하는데 없을 경우 map 자체에서 2번째 인자로 넘겨주는 인덱스 값을 넣어주면 된다 */}
        {/* key값은 그 배열 안에서만 고유하면 되고 그 밖으로는 같은 값이 중복되어도 상관없다 */}
        {products.map((product, index) => {
          return (
            <li key={index}>
              <article>
                <h3>{product.name}</h3>
                <p>{product.price}</p>
              </article>
            </li>
          );
        })}
      </ul>
    </div>
  );
}

products.json, sale_products.json

[
  {
    "name": "jeans",
    "price": "20"
  },
  {
    "name": "y-shirt",
    "price": "30"
  },
  {
    "name": "pants",
    "price": "70"
  }
]
[
  {
    "name": "snacks",
    "price": "5"
  },
  {
    "name": "socks",
    "price": "3"
  }
]

View


profile
Backend Engineer

0개의 댓글