프론트엔드 공부/React

40일차 프론트엔드 공부 - map

프망생222 2024. 12. 8. 17:29

- 프론트엔드 공부 40일차 -


Map

 

실무에서는 for문 보다는 map을 더 많이 사용한다,

map문이 유지보수에 더 좋기 때문

 

const classmates = [“짱구”, “철수”, “영희”]

classmates.map((el) => (el + “어린이”))

-> 배열 갯수만큼 해당 반복문이 계속된다.

- [“짱구어린이”, “철수어린이”, “영희어린이”]

 

const classmates = [

{ name : “짱구” },

{ name : “철수” }, 

{ name : “영희” }

]

classmates.map((el) => ({name : el.name + “어린이”}))

 

-  [

{ name : “짱구어린이” },

{ name : “철수어린이” }, 

{ name : “영희어린이” }

]

 

화살표 함수의 소괄호는 상황에 따라 생략 가능하다

 

ex) classmates.map((el) => (el + “어린이”))

classmates.map((el) => el + “어린이”) -> 가능

 

classmates.map((el) => ({name : el.name + “어린이”}))

classmates.map((el) => {name : el.name + “어린이”}) -> 불가능

 

map 과 html의 연결

const classmates = [“짱구”, “철수”, “영희”]

const aaa = classmates.map((el) => <div>{el}</div>)

-> const aaa = [<div>짱구</div>, <div>철수</div>, <div>영</div>] 같은 것을 의미한다

 

export default function AAA() {

const aaa = [<div>짱구</div>, <div>철수</div>, <div>영희</div>]

return <div>{aaa}</div>

}

 

<div>

<div>짱구</div>

<div>철수</div>

<div>영희</div>

</div>



map 예시

//컴포넌트 위에 만든 이유 : 컴포넌트가 리렌더링돼도 다시 안만들어짐 - 효율적
const FRUITS = [
  { number: 1, title: "레드향" },
  { number: 2, title: "샤인메스켓" },
  { number: 3, title: "딸기" },
  { number: 4, title: "사과" },
  { number: 5, title: "한라봉" },
  { number: 6, title: "망고" },
  { number: 7, title: "천혜향" },
  { number: 8, title: "귤" },
  { number: 9, title: "애플망고" },
  { number: 10, title: "메론" },
];

export default function MapFruitsPage() {
  const aaa = [
    <div>1 레드향</div>,
    <div>2 사과</div>,
    <div>3 딸기</div>,
    <div>4 메론</div>,
  ];

  const bbb = FRUITS.map((el) => (
    <div>
      {el.number} {el.title}
    </div>
  ));

  return (
    <div>
      <div>{aaa}</div>
      ----------------------
      <div>{bbb}</div>
      ---------------------
      <div>
        {/* 실무에서 사용하는 방법 */}
        {FRUITS.map((el) => (
          <div>
            {el.number} {el.title}
          </div>
        ))}
      </div>
    </div>
  );
}

 

 

 

map을 이용하여 backend 데이터 가져오기 

 

예제

import { useQuery, gql } from "@apollo/client";

const FETCH_BOARDS = gql`
  query {
    fetchBoards {
      number
      writer
      title
      contents
    }
  }
`;

export default function StaticRoutingMovedPage() {
  const { data } = useQuery(FETCH_BOARDS);
  console.log(data?.fetchBoards);

  return (
    <div>
      {data?.fetchBoards.map((el) => (
        <div>
          <span>
            <input type="checkbox" />
          </span>
          <span style={{ margin: "10px" }}>{el.number}</span>
          <span style={{ margin: "10px" }}>{el.title}</span>
          <span style={{ margin: "10px" }}>{el.writer}</span>
        </div>
      ))}
    </div>
  );
}

 

 

 

key

map을 사용할 때는 key를 사용하자

key가 있다면 어떤 값이 수정되었는지 빠르게 감지할 수 있다.

key는 중복되지 않은 값이어야 한다.(유일한 값을 사용해야 한다,)

만약 key 값을 지정해주지 않는다면 index가 기본 값으로 사용된다.

-> id를 key로 사용하는 것을 권장

 

 

key 주의사항

index를 key를 사용할때는 주의해야 한다.

데이터를 삭제하다보면 index가 중복될 수 있다.(유일하지 않음)

 

예시

import { useQuery, gql, useMutation } from "@apollo/client";

const FETCH_BOARDS = gql`
  query {
    fetchBoards {
      number
      writer
      title
      contents
    }
  }
`;

const DELETE_BOARD = gql`
  mutation deleteBoard($number: Int) {
    deleteBoard(number: $number) {
      message
    }
  }
`;

export default function StaticRoutingMovedPage() {
  const { data } = useQuery(FETCH_BOARDS);

  const [deleteBoard] = useMutation(DELETE_BOARD);

  console.log(data?.fetchBoards);

  const onClickDelete = (event) => {
    deleteBoard({
      variables: {
        number: Number(event.target.id),
      },
      refetchQueries: [{ query: FETCH_BOARDS }],
    });
  };

  return (
    <div>
      {data?.fetchBoards.map((el) => (
        <div key={el.number}>
          <span>
            <input type="checkbox" />
          </span>
          <span style={{ margin: "10px" }}>{el.number}</span>
          <span style={{ margin: "10px" }}>{el.title}</span>
          <span style={{ margin: "10px" }}>{el.writer}</span>
          <span>
            <button id={el.number} onClick={onClickDelete}>
              삭제
            </button>
          </span>
        </div>
      ))}
    </div>
  );
}

 

삭제 버튼 클릭 시

{data?.fetchBoards.map((el) => (
        <div key={el.number}>
          <span>
            <input type="checkbox" />
          </span>
          <span style={{ margin: "10px" }}>{el.number}</span>
          <span style={{ margin: "10px" }}>{el.title}</span>
          <span style={{ margin: "10px" }}>{el.writer}</span>
          <span>
            <button id={el.number} onClick={onClickDelete}>
              삭제
            </button>
          </span>
        </div>
      ))}

 

 

  const onClickDelete = (event) => {
    deleteBoard({
      variables: {
        number: Number(event.target.id),
      },
      refetchQueries: [{ query: FETCH_BOARDS }],
    });
  };

 

refetchQueries란?

데이터가 변경되었을 경우 최신 데이터로 다시 fetch해주기 위해 사용한다.

해당 예시에서는 삭제 버튼 터치 시 자동으로 목록을 새로고침해주고 있다.

만약 refetchQueries를 사용하지 않는다면 삭제 버튼을 터치하여도 목록이 삭제하기 전과 동일하게 나오게 된다.(DB 상에서는 해당 데이터는 삭제됨)