[TIL] 23.04.26

Minkyu Shin·2023년 4월 26일
0

TIL

목록 보기
15/44
post-thumbnail

오늘의 나는 무엇을 배웠을까?

1. 배열 렌더링 하기

1-1. map 으로 배열 렌더링

배열 렌더링을 하기 위해서 다음과 같이

//Child
import React from "react";

export default function Child({ name }) {
  return <li>name : {name}</li>;
}

Child 컴포넌트를 만들고

//ShowName
import React from "react";
import Child from "./Child";

export Default ShowName() {
  const names = ['a', 'b', 'c', 'd', 'e'];
  
  return (
    <div>
      <h1>이름 목록</h1>
      <ul>
        <Child name={ names[0] }/>
        <Child name={ names[1] }/>
        ...
      </ul>
    </div>
  )
}

ShowName 컴포넌트를 만든 뒤

//App
import ShowName from "./ShowName";

export default App() {
  return (
    <div>
      <ShowName />
    </div>
  )
} 

ShowName 컴포넌트를 불러와 렌더링할 수도 있다. 하지만, 값을 내려주기 위해 일일이 작성하는 것은 매우 비효율적이다.
이때 사용할 수 있는 것이 배열의 map 메소드이다.

map 메소드는 배열의 메소드로써, 배열에 함수를 호출하여 새로운 배열을 만들게 된다.
배열의 각 요소에 한번씩 함수를 호출하고, 빈 요소에 대해서는 호출하지 않는다. 또, 기존 배열은 수정되지 않은채 새로운 배열을 만들게 된다.

map 메소드를 활용하면 다음과 같이 코드를 수정할 수 있다.

//ShowName
//...
export default ShowName() {
  const names = ['a', 'b', 'c', 'd', 'e'];
  
  return (
    <div>
      <h1>이름 목록</h1>
      <ul>
        { names.map((name) => <Child name={name} />) }
      </ul>
    </div>
    )
}

배열 요소마다 한번씩 함수를 호출하여 해당 요소를 prop으로 가진 Child 컴포넌트를 생성한다. 매우 간단해 졌다.
고로, 배열을 렌더링 할 떄는 map 메소드를 적극 활용하자.

1-2. sort 로 정렬

배열의 sort 메소드를 통해 정렬해 줄 수 있다.

  • array.sort([compare function])
    매개변수로 비교함수를 받고, 원본 배열을 직접 변경하여 정렬된 배열을 반환하는 메소드이다.
    기본적으로는 문자열의 유니코드 포인트 값에 따라 정렬이 된다. 숫자형도 문자열로 일시적 변환후 정렬 된다.
  • 비교함수 (compare function)
    정렬 순서를 정의하는 함수로써, 매개변수로 비교함수가 전달되지 않으면 유니코드 포인트 값에 따라 정렬된다.

비교함수의 형식은

function compare(a,b) {
  if (a is less than b by some ordering criterion) {
    return -1;
  }
  if (a is greater than b by the ordering criterion) {
    return 1;
  }
  // a must be equal to b
  return 0;
}

과 같고, 두개의 매개변수를 받고 내부 로직을 실행하여 비교한다.

  • 반환 값이 음수이면 a를 b보다 낮은 index로 정렬, a가 먼저 오게 됨
  • 반환 값이 양수이면 b를 a보다 낮은 index로 정렬, b가 먼저 오게 됨
  • 반환 값이 0이면 a,b를 서로에 대해 변경하지 않고 모두 다른 요소에 대해 정렬

1-3. filter 로 아이템 삭제

//ReviewList.js
function ReviewListItem({ item, onDelete }) {
  const handleDeleteClick = () => onDelete(item.id);

  return (
    <div className="ReviewListItem">
      <img className="ReviewListItem-img" src={item.imgUrl} alt={item.title} />
      <div>
        <h1>{item.title}</h1>
        <p>{item.rating}</p>
        <p>{formatDate(item.createdAt)}</p>
        <p>{item.content}</p>
        <button onClick={handleDeleteClick}>삭제</button>
      </div>
    </div>
  );
}

function ReviewList({ items, onDelete }) {
  return (
    <ul>
      {items.map((item) => {
        return (
          <li key={item.id}>
            <ReviewListItem item={item} onDelete={onDelete} />
          </li>
        );
      })}
    </ul>
  );
}
//App.js
function App() {
//~~~
  const handleDelete = (id) => {
    console.log(items);
    const nextItems = items.filter((item) => item.id !== id);
    setItems(nextItems);
  };
  
  //~~~

  return (
      <div>
        <div>
          <button onClick={handleNewestClick}>최신순</button>
          <button onClick={handleBestClick}>베스트순</button>
        </div>
        <ReviewList items={sortedItems} onDelete={handleDelete} />
        {hasNext && <button onClick={handleLoadMore}>더 보기</button>}
      </div>
    );
}

위와 같은 코드가 있다면, handleDelete 함수는 filter 메소드를 이용하여 item.id 값이 일치하지 않는 배열의 요소만 추출하여 새로운 배열을 만들게 된다. 즉, item.id를 id 값으로 갖는 원소만 제거하는 것과 동일해 진다.

ReviewListItem 컴포넌트의 삭제 버튼이 클릭될 때 props로 받아올 onDelete 함수의 매개변수로 item.id 가 전달되어야 한다. onDelete 함수는 ReviewList 에서도 전달 받으며 그대로 ReviewListItem 컴포넌트에 전달된다.

1-4. 배열 렌더링 시 key가 필요한 이유

배열을 렌더링 할 때, 의도하지 않는 방식의 결과가 나타나거나 비효율적인 동작을 막기 위해 key를 사용해야 한다.

가령, 아래와 같은 배열을

const array = ["a", "b", "c", "d"];

다음과 같이 렌더링 한다고 할 때

array.map(item => <div>{item}</div>);

b 와 c 사이에 새로운 요소 z를 삽입하게 되면,

<div>b</div><div>c</div> 사이에 새로운 태그를 삽입하는 것이 아닌, c → z / d → c / 마지막에 d 가 새로 삽입되는 과정으로 re-rendering이 일어나게 된다.

또한, a가 제거 되면 a→b / b→c / c→d / 마지막의 d가 제거되는 과정으로 re-rendenring이 일어나는 매우 비효율적인 동작을 하게 된다.

Key를 활용하면 이러한 불필요한 작업을 개선시킬 수 있는데,

[
  {
    id: 0,
    text: 'a'
  },
  {
    id: 1,
    text: 'b'
  },
  {
    id: 2,
    text: 'c'
  },
  {
    id: 3,
    text: 'd'
  }
];

위의 id와 같이 key로 사용할 수 있는 고유값이 객체에 있고,

array.map(item => <div key={item.id}>{item.text}</div>

와 같이 렌더링을 한다면 배열이 업데이트 되어도 수정되지 않는 기존 값은 그대로 두고 원하는 곳에 내용을 삽입하거나 삭제할 수 있게 된다. 훨씬 더 효율적인 렌더링을 할 수 있게 되는 것이다.

오늘의 나는 어떤 어려움이 있었을까?

사실 아직 props state에 대해 잘 모르겠다. React를 사용하며 가장 중요한 두 요소인 것 같은데, 내일 보충학습을 통해 제대로 알아보고 학습을 진행해야 겠다.
뭔가 느낌상 하나를 제대로 모른채로 넘어가니 뒷내용도 어영부영 되는 느낌이 있는 것 같은데, 시간을 조금 더 들여 이해하려고 노력해야겠다.

내일의 나는 무엇을 해야할까?

  • 팀 데일리 미션 출제 및 답변
  • React 데이터 다루기 강의
  • 보충학습, 멘토링
profile
개발자를 지망하는 경영학도

0개의 댓글