Today Sangmin Learned
article thumbnail
Published 2021. 11. 26. 14:15
[React] JSON 배열 상태관리 Web/React
728x90

오늘 성공한건 카테고리를 눌렀을 때 그 카테고리를 가진 JSON 배열을 띄워주는 것이었는데, 처음 해본건데 돼서 신기했다.

const menuArray = [
  {
    id: 1,
    category: "커피",
    name: "아메리카노(ICE)",
    price: "4,100원",
    imgUrl: Americano,
  },
  {
    id: 2,
    category: "커피",
    name: "아메리카노(ICE)",
    price: "4,100원",
    imgUrl: Americano,
  },
  {
    id: 3,
    category: "에이드",
    name: "사과에이드",
    price: "5,200원",
    imgUrl: Americano,
  },
  {
    id: 4,
    category: "커피",
    name: "아메리카노(ICE)",
    price: "4,100원",
    imgUrl: Americano,
  },
  {
    id: 5,
    category: "디저트",
    name: "다쿠아즈",
    price: "1,800원",
    imgUrl: Americano,
  },
  {
    id: 6,
    category: "디저트",
    name: "마카롱",
    price: "2,500원",
    imgUrl: Americano,
  },
  {
    id: 7,
    category: "커피",
    name: "아메리카노(ICE)",
    price: "4,100원",
    imgUrl: Americano,
  },
  {
    id: 8,
    category: "베이커리",
    name: "크림빵",
    price: "1,800원",
    imgUrl: Americano,
  },
];

이렇게 데이터가 있다고 했을 때,

  const CoffeeList = menuArray.filter((data) => {
    return data.category === "커피";
  });

  const DeesertList = menuArray.filter((data) => {
    return data.category === "디저트";
  });

  const BakeryList = menuArray.filter((data) => {
    return data.categpry === "베이커리";
  });

  const AdeList = menuArray.filter((data) => {
    return data.category === "에이드";
  });

이렇게 카테고리에 근거해서 filter 함수를 써서 걸러낸 값을 각 List 변수에 부여했다. 이렇게 되면 각 List 변수에는 카테고리를 포함한 모든 값이 다 들어가게 된다. 그렇지만 CoffeeList인 경우 category: "커피" 인 경우만 들어가게 된다.

  const handleButtonClick = (e) => {
    setMenu(e.target.value);
    console.log(e.target.value);
    if (e.target.value === "커피") {
      setTargetArray(CoffeeList);
    } else if (e.target.value === "에이드") {
      setTargetArray(AdeList);
    } else if (e.target.value === "디저트") {
      setTargetArray(DeesertList);
    } else if (e.target.value === "베이커리") {
      setTargetArray(BakeryList);
    }
  };

if문 코드가 더럽긴 한데.. 화면에서 카테고리 버튼을 눌렀을 때 이 카테고리를 가진 리스트에 해당하는 값들을 targetArray로 지정을 해줬다. 그다음 이 targetArray를 return문에서

      <TitleWrap>
        {TitleArray.map((menu, idx) => {
          return (
            <MenuBtnLabel id="menu" key={idx}>
              <InputWrap
                type="radio"
                name="menu"
                value={menu}
                id="menu"
                defaultChecked={menu === "커피"}
                onChange={handleButtonClick}
              ></InputWrap>
              <ButtonWrap>{menu}</ButtonWrap>
            </MenuBtnLabel>
          );
        })}
      </TitleWrap>
	  <MenuListWrap>
        {targetArray.map((menu) => (
          <>
            <MenuWrap key={menu.id} id={menu.id}>
              <img
                style={{ width: "43px", height: "61px" }}
                src={menu.imgUrl}
                alt={menu.name}
              />
              <MenuNameWrap>{menu.name}</MenuNameWrap>
              <MenuNameWrap>{menu.price}</MenuNameWrap>
            </MenuWrap>
          </>
        ))}
      </MenuListWrap>

이렇게 map의 대상으로 불러온 다음 하나하나 출력을 해주는 방식으로 진행했다.

아직 미완성이다. 문제는 우리가 처음 키오스크를 접했다고 했을 때 보통은 첫번째 카테고리에 기본적으로 고정이 되어있는 상태에서 다른 카테고리를 눌러서 들어가는 방식이기 때문에 처음 이 페이지에 들어갔을 때는 커피에 해당하는 JSON값이 출력이 되어있어야 한다는 것인다. 근데 커피에 해당하는 JSON 값 출력은 움짤에서 보다시피 했지만 저 카테고리 버튼이 처음에 커피에 focusing이 되어있게 하는 방법은 아직 모르겠다..

-> defaultChecked 성질을 이용하면 됐다. radio display에서 defaultChecked를 사용하면 페이지에 들어가자마자 처음으로 체크되어있는 값을 설정할 수 있다. 나는 첫번째 카테고리가 커피이므로 커피로 설정했다. 그렇지만 이 defaultChecked로 설정한 값은 위에서 선언한 handleButtonClick 함수를 실행시키지 않으므로, targetArray의 초기값을 CoffeeList로 해줘야 한다.

let [targetArray, setTargetArray] = useState(CoffeeList);

여기서 targetArray의 값은 누를 때마다 바뀌므로 let을 이용해서 선언해줬다. 이렇게 해도 되는지 모르겠는데;; const로 하면 안 된다. ㅋㅋ 아마 매번 targetArray의 값을 바꿔주기 때문에 const를 사용하면 안되는 것 같다.

 

자세한 코드가 궁금하면 댓글로 남겨주세요.

 

profile

Today Sangmin Learned

@steadily-worked

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!