[React]-useEffect 의존성 배열에 추가해보자!

badassong·2023년 4월 5일
0

React

목록 보기
28/56
post-thumbnail

앞서 상품목록 토글을 만든 것에 이어서,
체크박스를 하나 만들어서 체크할 땐 세일하는 상품목록만 뜨게 하는 코드를 짜보았다!

AppProducts.jsx

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

export default function AppProducts() {
  const [showProducts, setShowProducts] = useState(true);
  return (
    <div>
      {showProducts && (
        <Products/>
      )}
      <button
        onClick={() => {
          setShowProducts((prev) => !prev);
        }}
      >
        Toggle
      </button>
    </div>
  );
}

Products.jsx

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

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

  useEffect(() => {
    fetch(`data/${checked ? "sale_" : ""}products.json`)
      .then((res) => res.json())
      .then((data) => {
        console.log("🔥뜨끈한 데이터를 네트워크에서 받아옴");
        setProducts(data);
      });
    return () => {
      console.log("🧹 깨끗하게 청소하는 일들을 합니다.");
    };
  }, [checked]);

  return (
    <>
      <input
        id="checkbox"
        type="checkbox"
        checked={checked}
        onChange={handleChange}
      />
      <label htmlFor="checkbox">Show Only 🔥 Sale</label>
      <ul>
        {products.map((product) => (
          <li key={product.id}>
            <article>
              <h3>{product.name}</h3>
              <p>{product.price}</p>
            </article>
          </li>
        ))}
      </ul>
    </>
  );
}

이렇게 하면 체크박스를 눌렀을 때 세일품목만 뜬다!

의존성배열에 아무것도 추가하지 않으면 컴포넌트가 처음에 mount됐을 때만 콜백함수가 호출이 되는데, checked 값이 변경될 때마다 useEffect가 실행되어야 한다면 의존성배열에 checked를 추가해주면 된다!!

그런데 여기서!
체크한 상태에서 토글을 눌렀을 때 그 데이터가 그대로 뜨게 할 순 없을까?
토글버튼을 누르면 Products 컴포넌트가 unmount되면서 상태값들이 사라지게 되므로 unmount되었을 때도 상태값이 유지되게 하기 위해 checked state와 handleChange함수를 AppProducts.jsx에 추가해보기로 했다!

AppProducts.jsx

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

export default function AppProducts() {
  const [showProducts, setShowProducts] = useState(true);
  const [checked, setChecked] = useState(false);
  const handleChange = () => setChecked((prev) => !prev);

  // 체크박스에 체크한 상태에서 토글을 눌렀을 때 계속 세일상품목록이 뜨게하기 위해서
  // checked state와 handleChange 함수를 여기에 추가해줌!
  return (
    <div>
      {showProducts && (
        <Products checked={checked} handleChange={handleChange} />
      )}
      <button
        onClick={() => {
          setShowProducts((prev) => !prev);
        }}
      >
        Toggle
      </button>
    </div>
  );
}

그리고 props로 넘겨주기!

Products.jsx

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

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

  useEffect(() => {
    fetch(`data/${checked ? "sale_" : ""}products.json`)
      .then((res) => res.json())
      .then((data) => {
        console.log("🔥뜨끈한 데이터를 네트워크에서 받아옴");
        setProducts(data);
      });
    return () => {
      console.log("🧹 깨끗하게 청소하는 일들을 합니다.");
    };
  }, [checked]);

  return (
    <>
      <input
        id="checkbox"
        type="checkbox"
        checked={checked}
        onChange={handleChange}
      />
      <label htmlFor="checkbox">Show Only 🔥 Sale</label>
      <ul>
        {products.map((product) => (
          <li key={product.id}>
            <article>
              <h3>{product.name}</h3>
              <p>{product.price}</p>
            </article>
          </li>
        ))}
      </ul>
    </>
  );
}

이렇게 했더니 체크한 상태에서 토글하면 그 상태값이 그대로 유지가 된다!

profile
프론트엔드 대장이 되어보쟈

0개의 댓글