React - 반복문 (map, filter)

타다닥·2024년 2월 1일
0
post-thumbnail

🧸
이 내용도 작년 12월에 작성해놓은 내용..! 개인 노션에 정리 후 벨로그 옮기는 것, 늦게 업로드하니 좋다.
이때는 정말 헷갈려 했던 내용이다. 어떻게 써야하는지도 모르겠고 일단 수업은 나갔으니 정리는 해야겠고 해서 나름 공부하면서 정리해놓은 내용.

이제와서 벨로그를 올리기 전 내용을 한 번 훑으면서 복습도 하니, 내가 새롭게 알게 된 내용들도 보여진다. 그리고 지금은 어렵지 않은 내용인데 왜그렇게 어려워했나 싶기도 하다. 물론 복잡하게 활용하라면 못하겠지만..! 그래도 역시 뭐라도 해가면서, 직접 써가면서 배우는게 더 크게 남는 것 같다! 지금 어려운 것도 언젠가는 쉽게 할 수 있는 날이 오,,,겠지,,,,,,,,,,


React에서의 반복문

▶️ map()을 이용한 반복

  • 배열 데이터를 효율적으로 사용하기 위해 사용한다.
    • 예를 들어 상품목록이 배열이 있고 각각의 상품을 보여주는 컴포넌트를 작성한다고 했을 때, 상품이 100개라면 100개의 코드를 각각 작성하는것이 아니라 map()을 사용할 수 있다. 반복되는 코드를 렌더링 할 때 사용 하는 것!
  • arr.map(callbackFunction, [thisArg])
    • callbackFunction: 새로운 배열의 요소를 생성하는 함수로, currentValue, index, array 3개의 인수를 가질 수 있다.
    • [this.Arg] : 생략 가능한 것으로 callbackFunction 에서 사용할 this 객체이다.
  • map()은 앞에 들어온 배열 요소를 쭉 돌아다니게 된다. map()의 인자로 있는 콜백함수의 return을 통해 값을 내보내게 되는데, 이 때 조건에 따른 새로운 배열을 생성 해준다. 결국 원하는 형태로 반환이 가능하게 되는 셈!

Key

  • React에서 map() 을 사용하면서 꼭 필요한 속성이 key이다.
  • 기존 요소와 업데이트 된 요소를 비교하는데에 사용된다. (리액트가 이 key값을 통해 어떤 요소가 업데이트 되었는지 알 수 있다.)
  • 다른 요소와 겹쳐지지 않는 고유한 값 이어야 한다. (배열의 요소 중 고유한 값이 있다면 key로 이용해도 된다. 예를 들어 id값과 같은..!)
//-----------이런식으로 사용해준다.
{배열.map((element, index)=>{
  return <FunctionProps name = {element.name} key = {index} />;
})}

//-----------예시 1
const nameList = [
{name : "dana"},
{name : "jun"},
{name : "joy"},
];

//이렇게 return (key값을 주기 위해 index도 가져온다.
<ul>
	{nameList.map((element, index)=>(
		<li key={index}>{element.name}</li>
		)       
	)}
</ul>

//여기서 element는 정해진 용어가 아니다! 어떤 요소인지 알아 볼 수 있도록 임시 이름을 작성하는걸로 생각!
//단 map에서 element라고 명시했다면, 가져올 때에도 element.내용 이런식으로 통일시켜주어야 한다.

//오브젝트의 점 접근법으로 props를 전달한다. (element.name)
//map이 배열 요소 전체를 쭉 돌기 때문에 결국 배열의 개수만큼 컴포넌트가 생성된다.

//고유한 값(id 등)이 존재하지 않는다면 index로 사용해도 된다. 
//단 index를 사용하는 것은 최후의 수단이다.
//만약 리스트의 순서가 변경되면 모든 key값도 바뀌게 되기 때문.

//출력 결과
//dana
//jun
//joy

//-----------예시 2
const [list, setList] = useState([
{id: 1, text: "a"}, 
{id: 2, text: "b"}, 
{id: 3, text: "c"},
]);

return (
  <>
  <ol>
    {list.map((value)=>{
        return <li key = {value.id}> {value.text} </li>
    })}
  </ol>
  </>
);

//이 경우 list 형태로 보여지게 된다.
//1.a
//2.b
//3.c

▶️ filter()를 이용한 필터링

  • filter() 의 인자로 넘겨지는 callback함수의 테스트(조건)를 통과하는 요소를 모아서 새로운 배열을 반환 해준다. (배열에서 원하는 값을 삭제 할 수 도 있다!)
  • return 값은 조건이 되어야 한다. 조건이 true일 경우 해당 원소가 배열에 포함되기 때문.
let animals = ["dog", "cat", "panda"];

let zoo = animals.filter((animal)=>{return animal.length > 3});
console.log(zoo); //length의 길이가 3이상인  panda출력. 

let animalAgroup = animals.filter((animal) => {
    return animal.includes("a");
  });
  console.log(animalAgroup); // cat, panda 출력.

▶️ map()과 filter()를 이용한 예시

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

function ListMap() {
  const productList = [
    { id: 1, product: "가방" },
    { id: 2, product: "패딩" },
    { id: 3, product: "신발" },
    { id: 4, product: "상의" },
    { id: 5, product: "하의" },
  ];
  const [list, setList] = useState(productList);
  const [newProduct, setNewProduct] = useState("");

  //map은 앞에 있는 배열에 대해서 반복을 하면서, map의 인자로 넘어가는 콜백함수의 return값을 이용해 새로운 배열을 생성.

  const addProduct = (e) => {
    //list와 추가할 객체를 합쳐줘야함
    //원래라면 새로운 상품을 back에서 insert하고 생긴 primary값을 id에 담아주면 좋다. 지금은 임시로 length사용
    const newObj = { id: list.length + 1, product: newProduct };

    //기존 [list]에 스프레드 연산자통해서 가져온다. 모든거 다 풀어서 가져오는거. (...list)
    // const newList = [...list, newObj];

    //이렇게 해도 된다!
    //concat() 메소드는 인자로 주어진 값을 기존 배열에 합쳐서 새로운 배열을 반환해준다.
    const newList = list.concat(newObj);

    //push하면 안되나?
    //state변수 변경할때는 setter사용해야한다. 그래서 newObj만들고 한 것.

    //setList
    setList(newList);
    setNewProduct("");
  };

  const deleteProduct = (id) => {
    //더블클릭한 상품에 대해서 삭제를 해야한다.  이 때 filter 이용!
    //filter 메소드 (return되는 값은 조건. 이 조건을 만족하면 true가 되니 그 배열이 반환된다.)
    //앞에 있는 배열에 대해 반복을 한다.
    //filter메소드의 return 값은 조건이 되더야 한다. 조건이 true일 경우 해당 원소는 배열에 포함된다.
    //조건이 false일 경우 배열에 포함하지 않는다.
    //클릭한게 아닌 값들이 남겨져야 하니 아래 조건 작성.
		//(선택한 리스트는 삭제되고 나머지는 남아야 하니, 나머지 배열을 setList에 담아주는 것)
    const newList = list.filter((value) => value.id != id);
    //rendering할 때 list배열을 이용함. list배열에서 원하는 원소를 삭제해야 한다. 삭제한 상품의 고유 키값을 사용.
    //삭제된 버전의 배열을 setList를 이용하여 list의 상태를 변경.
    setList(newList);
  };
  return (
    <>
      <label>추가할 상품: </label>
      <input
        type="text"
        value={newProduct}
        onChange={(e) => {
          setNewProduct(e.target.value);
        }}
      />
      <button onClick={addProduct}>추가하기</button>
      <ul>
        {list.map((value, i) => {
          return (
            <li
              style={{ cursor: "pointer" }}
              key={value.id}
              onDoubleClick={() => {
                deleteProduct(value.id);
              }}
            >
              {value.product}
            </li>
          );
        })}
      </ul>
    </>
  );
}

export default ListMap;
profile
프론트엔드 ㄱH발ㅈr ㅎH보ㅈr - ☆

0개의 댓글