React 심화- 배열 순회 시 key와 index

최중혁·2022년 6월 5일
0

React

목록 보기
13/13

React 배열 순회시(map,forEach) 시 key의 필요성

/*인터페이스*/
export interface BookListProps {
  bookList: NewBook[];
}

export interface BookItemProps {
  book : NewBook;
}
export interface Book {
  id:string;
  userName:string;
  title:string;
  description:string;
}
export interface NewBook {
  id:string;
  userName:string;
  title:string;
  description:string;
  bookMark: boolean;
}

const [{ data: getData, loading: getLoading, error: getError },] =
		useAxios<NewBook[]>(
			{
				method: 'GET',
				url: 'https://api.jsonbin.io/b/616cd47a9548541c29c49b36',
			}
    );
  getData&& getData?.forEach((iter)=>
    iter.bookMark=false
  )

return (
				<>
          {getData.map((iter, index) =>
            <BookItem book={iter}/>
          )}
        </>
)

export const BookItem=(props: BookItemProps)=>{
  const { book }=props;
  
  
  return (
    <div style={{position:'relative', marginRight:16}}>
      <img
        alt="book"
        className={styles.Book}
        src={require('../assets/Book.png')}
      >
      </img>
    <div className={styles.BookCon}>
      <div className={styles.BookTitle}>
        {book.title}
      </div>
      <div className={styles.BookDes}>
        {book.description}
      </div>
    </div>
  
    </div>
    
  )
}

⇒위의 코드 예시처럼 진행하면, BookItem 의 배열은 보기에는 component가 순회하여 DOM에 제대로 작동되는 듯이 보인다.

그러나 고유한 key 값에 따라 분류된것이 아니기 때문에,

export const BookItem=(props: BookItemProps)=>{
  const { book }=props;
  **const [markState,setMark]=useState<boolean>(book.bookMark);**
  
  return (
    <div style={{position:'relative', marginRight:16}}>
      <img
        alt="book"
        className={styles.Book}
        src={require('../assets/Book.png')}
      >
      </img>
    <div className={styles.BookCon}>
      <div className={styles.BookTitle}>
        {book.title}
      </div>
      <div className={styles.BookDes}>
        {book.description}
      </div>
    </div>
  
    </div>
    
  )
}

⇒추가된 markState와 props에서 넘어온 book.bookmark를 console.log 로 찍어보면,

두개의 값이 다르다는 걸 알 수 있다. 고유한 key 값에 따라 분류된것이 아니기 때문에, bookItem마다 props에서 내려온 값이 변하는 것을 감지하지 못하기 때문이다.

그러므로 이를 해결하기 위해서는

<>
          {getData.map((iter, index) =>
            <BookItem key={iter.id} book={iter}/>
          )}
        </>

key의 고유값을 설정 해주는 것이 좋다.

심화- Key 대신 index를 쓴다면?

index 를 key값으로 쓴다면 정적 배열인 경우에는 크게 차이가 나지 않는다.

하지만, 배열의 값은 변할 수가 있고, 배열의 길이 역시도 바뀌기 때문에 index로 조회한다면 해당 index의 값은 바뀌기 마련이다. ⇒ 치명적인 overange나 undefined 에러가 발생하게 된다.
=>Virtual DOM을 비교하는 과정에서 Key가 없을 때, 배열을 순차적으로 비교하면서 변화를 감지.
하지만, key가 있다면 이 값을 사용하여 어떤 변화가 일어났는지 더욱 빠르게 알 수 있다.

0개의 댓글