[React] 댓글 추가 기능 feat.map()

Joah·2022년 6월 12일
0

React

목록 보기
13/31

map()

map함수?

mdn에서의 map 메소드에 대한 정의
배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환합니다.

  • 보통 배열 안에 요소들을 순환할 때, for 반복문을 사용한다.

  • 하지만 항상 for(let i = 0; i < array.length; i++)을 작성하기에는 코드도 길고 개발자들이 지양하는 귀찮음을 수반한다.

  • 따라서 forEachmap메소드가 등장하여 코드를 더욱 깔끔하고 직관적으로 작성할 수 있게 한다.

  • 배열안의 요소를 순환할 뿐만아니라 callback함수를 지정하여 각 요소에 해당 callback함수를 적용한다.

    사용법
    array.map(callbackFunction(currenValue, index, array), thisArg)

  • 첫 번째 인수 외에는 모두 optional한 인수이다. 필요하면 사용하는 것


댓글 추가 기능에 map함수를 사용하는 이유

[댓글1, 댓글2, 댓글3, 댓글4, .....]
  • 각 댓글을 배열의 요소로 지정한다.

  • 각 댓글을 배열의 요소로 추가하기 위해서 map함수를 적용한다.

  • 댓글 입력 창인 input에 어떠한 글이 작성되고 게시를 누르게 되면, 해당 글이 map함수를 통해서 댓글board에 추가되는 기능을 구현한다.

  • 각각의 요소의 index번호를 통해 추후 삭제 기능을 구현하기 위해 map함수의 두 번째 인자까지 작성한다.


대략적인 코드 설명

코드

component이름과 관계도

  • Main.js에는 댓글 창인 <input>
  • ReplyBoard.js에는 댓글이 쌓이는 공간을 <ul> 태그로 <ReplyBoard/> component

    -ReplyItems.js에는 각각의 업로드 된 댓글 <li> 태그로 <ReplyItems/> component


map함수에 key props를 부여

//ReplyBoard.js

import ReplyItems from './ReplyItems';

const ReplyBoard = props => {
  return (
    <div>
      {props.replyList.map((item, i) => (
        <ReplyItems
          item={item}
          index={i}
          setReplyList={props.setReplyList}
          replyList={props.replyList}
        />
      ))}
    </div>
  );
};

export default ReplyBoard;
  • map함수를 통해서 반환되는 요소(댓글)와 그 요소의 인덱스 번호를 각각 (item, i)로 지정했다.

  • ReplyItems component에 값을 넘겨주기 위해 <ReplyItems/>안에

    • items이라는 이름으로 {item}을 넘겨주고
    • index라는 이름으로 {i}를 넘겨주고
    • replyList의 상태를 업데이트 하는 setReplyList를 Main.js에서 받아왔기 때문에 setReplyList라는 이름으로{props.setReplyList}를 넘겨주고
    • 위와 동일하게 Main.js에서 받아온 replyListreplyList라는 이름으로 {prop.replyList}를 넘겨준다.



  • 따라서 위의 key props들을 ReplyItems.js에서 사용할 수 있다.

//ReplyItems.js

import React from 'react';
import './reply.scss';

const ReplyItems = props => {

  return (
    <li className="user">
      UserId <span className="replyItem">{props.item}</span>
      <button
        className="deleteReply"
        onClick={() => {
          let copy = [...props.replyList];
          copy.splice(props.index, 1);
          props.setReplyList(copy);
        }}
      />
    </li>
  );
};

export default ReplyItems;

댓글 추가 기능에 map함수에 key props를 부여하는 이유

React 공식문서
Key는 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕습니다. key는 엘리먼트에 안정적인 고유성을 부여하기 위해 배열 내부의 엘리먼트에 지정해야 합니다.
Key를 선택하는 가장 좋은 방법은 리스트의 다른 항목들 사이에서 해당 항목을 고유하게 식별할 수 있는 문자열을 사용하는 것입니다. 대부분의 경우 데이터의 ID를 key로 사용합니다.


map함수 적용시 key props를 부여하는 이유?
React에서 key는 어떤 항목을 변경할지 추가할지 삭제할지 식별할 수 있게 한다.

그래서 댓글배열에 map함수를 돌렸을때 key값을 주지않아 warning이 떴다.
따라서 map의 두번째 인자인 index를 이용하여 데이터에 key값을 주었다.

하지만 이는 좋은방법이 아니라는 것을 알게 되었다.
댓글이라는 것은 고유하지 않고 삭제 혹은 추가가 가능하다.

이렇듯 뒤바뀔 수 있는 항목들을 map의 index로 부여한다면
데이터가 변경될때마다 다시 렌더링 되고 map의 index가 0부터 다시 맵핑되며
이전에 삭제되었던 항목 자리에 엉뚱한 index가 자리하게 될 수 있기 때문이다.

map 함수가 아닌 filter를 사용하는 경우도 많고 index값을 getDate함수를 사용하여 각각의 댓글의 id값을 밀리세컨드 단위로 부여하는 방법도 있다.

key값으로는 고유한 값이 가장 좋다.

대표적인 예로는 데이터의 id값!(인간의 주민등록번호라고 생각하면 된다. 사망한 사람의 주민번호를 다시 사용하지는 않으니 상당히 고유한 번호)

map의 index로 사용할 수 있는 경우는

배열의 요소가 절대불변할 경우에만 쓰도록!

출처: https://velog.io/@awaji0829/map-key-props


제대로 쓰려면, map() 함수 내부에 element에 key값을 넣어 주는게 좋다.

출처:https://velog.io/@hongduhyeon/React-map-key-props-index

profile
Front-end Developer

0개의 댓글