Lists & Keys

saeyoung.dev·2024년 3월 10일

React

목록 보기
7/9
post-thumbnail

컴포넌트의 고유한 key 부여

컴포넌트가 동시에 렌더링 될 경우(리스트), 컴포넌트를 구분하기 위한 key 값이 필요하다.

const numbers = [1, 2, 3, 4, 5];
const doubled =  numbers.map((number) => number * 2) // 각 아이템의 2배 저장
```![](https://velog.velcdn.com/images/effysogood/post/50761ac3-e43c-425b-8b93-889f7043ebd9/image.png)

### 리스트 만들기
1, 2, 3, 4, 5가 들어있는 numbers 변수를 표현하고 있는 number이라는 리액트 엘리먼트는 즉, 컴포넌트의 리턴 값이다. 그 리턴 값을 할당하고 있는 변수는 listItems 이다.

```javascript
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map(number => 
  <li>{number}</li>
)

그럼 array의 리턴 값을 할당하고 있는 변수 listItems는 아래 코드에서 <ul> 태그 안에 {} 를 사용하여 표현 가능
JSX {} 안에서는 어떠한 자바스크립트 표현도 가능하기 때문.

ReactDOM.render(
  <ul>{listItems}</ul>,
  document.getElementById('root')
)

리스트 안에는 <li> 가 만들어낸 리액트 엘리먼트가 여러개 들어가 있다. 그 엘리먼트끼리 구별이 쉽지 않다.
리액트의 입장에서 엘리먼트 내 들어 있는 값을 동일하게 인식한다. 구별을 하기 위해서는
바로 key 값을 추가해야 한다! 태그에는 key 값을 부여할 수 있는데, 리액트의 입장에서 key 값을 통해 구분할 수 있다. key는 string 값을 가지는 props 이다. 따라서 태그마다 고유한 key 값을 부여해야 한다.

function MemberList(props){
  const numbers = props.numbers;
  const listItems = numbers.map((numner) => {
    <li>{number}</li>
  })
  return(
    <ul>{listItems}</ul>
  )
}

const numbers = [1,2,3,4,5]
ReactDOM.render(
  <MemberList numbers={numbers}/>,
  document.getElementById('root')
)

Keys

key는 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕는다.
key는 엘리먼트 안에 안정적인 고유성을 부여하기 위해 사용된다. (해당 엘리먼트를 명확히 인지하는데 도움)
key는 map() 이 실행될 때 주어져야 한다

const numbers = [1,2,3,4,5]
const listItems = numbers.map(number => {
  <li key={number.toString()}>
    {number}
  </li>
})

가장 좋은 방법은 다른 엘리먼트들과 다른 UNIQUE한 string 값을 부여하는 것이다.

const todoItems = todos.map((todo) =>{
  <li key={todo.id}> 
    {todo.text}
  </li>
})

만약, 변하지 않고 고정적인 key 값을 부여하기 어려울 경우, index를 사용하여 부여 (하지만 주의점 있음)

const todoItems = todos.map((todo, index) =>
  // index를 이용하여 key값 부여하기
  <li key={index}>
    {todo.text}
  </li>
);

array 내 아이템의 순서가 바뀔 수 있음 (아이템이 삭제 되었거나 업데이트 되었을 경우)
인덱스를 키로써 사용하면 재정렬을 통해 컴포넌트 state에 문제가 발생할 수 있다.
컴포넌트 인스턴스는 키에 따라 업데이트되고 재사용 되는데 만약 키가 인덱스라면 아이템을 이동하면 해당 아이템이 변경된다. 그 결과로 제어되는 input 같은 컴포넌트 state가 예기치 않은 방식으로 혼합되고 업데이트될 수 있습니다.

index를 key값으로 부여할 경우 좋지 않은 이유 알아보기
더 자세히 알고 싶다면 왜 키가 필요한가? 에 대해 더 알아보세요. :)

JSX에서 map() 포함하기

  1. listItems 변수에 컴포넌트 배열 할당, JSX안에 그 변수를 {listItems} 형태로 작성
function ListItem(props) {
  // 배열값을 반환하지 않으니, 키 값을 지정하지 않습니다!
  return <li>{props.value}</li>;
}

function NumberList(props){
  const numbers =  props.numbers
  const listItmes = numbers.map(number => {
    <ListItem key={number.toString()} value={number} />
  })
  return(
    <ul>
    {listItems}
    </ul>
  )
}
  1. 때론 map() 전체를 JSX 안에 넣어 코드를 깔끔하게 유지
function NumberList(props) {
  const numbers = props.numbers;
  return (
    <ul>
      {numbers.map((number) =>
        <ListItem key={number.toString()}
                  value={number} />
      )}
    </ul>
  );
}

0개의 댓글