ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 리액트 주요개념 - 리스트와 key
    IT/리액트 2022. 1. 16. 01:22
    728x90

    여러개의 컴포넌트 렌더링하기

    엘리먼트 모음을 만들고 중괄호를 이용해 JSX에 포함시킬 수 있습니다.

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

    map() 함수를 사용해 numbers 배열을 반복 실행하면서 각 항목을 <li> 엘리먼트로 반환하고 listItem에 저장합니다.

    function ListAndKey() {
        return (
            <div>
                <ul>{listItems}</ul>
            </div>
        )
    }

    listItem 배열을 <ul> 엘리먼트 안에 포함하여 반환합니다.

    (저는 새로운 .js 파일을 생성하고 index.js 에서 호출하는 방식으로 코드를 작성했습니다.)

     

     

    기본 리스트 컴포넌트

    일반적으로 리스트 렌더링은 컴포넌트 안에서 이루어집니다. 위의 코드를 리팩토링하면 다음과 같습니다.

    const numbers = [1,2,3,4,5];
    
    function NumerList(props) {
        const numvers = props.numbers;
        const listItems = numbers.map((number) =>
            <li>{number}</li>
        );
        return (
            <ul>{listItems}</ul>
        );
    }
    
    function ListAndKey() {
        return (
            <div>
                <NumerList numbers={numbers} />
            </div>
        )
    }

    위의 코드를 실행하면 각 항목에 key를 넣어야 한다는 경고가 표시됩니다.

    F12로 확인 가능

    key: 엘리먼트 리스트를 만들 때 포함해야 하는 특수한 문자열 어트리뷰트
    function NumerList(props) {
        const numvers = props.numbers;
        const listItems = numbers.map((number) =>
            <li key={number.toString()}>  //키 설정
                {number}
            </li>
        );
        return (
            <ul>{listItems}</ul>
        );
    }

     

     

    Key

    React가 어떤 항목을 변경, 추가, 삭제할지 식별하는 것을 돕습니다. 엘리먼트에 안정적인 고유성을 부여하기 위해 배열 내부의 엘리먼트에 지정해야 합니다.

     

    key를 선택하는 가장 좋은 방법은 리스트의 다른 항목들 사이에서 해당 항목을 고유하게 식별할 수 있는 문자열을 사용하는 것입니다. 대부분 데이터의 ID를 key로 사용합니다.

     

    렌더링한 항목에 대한 안정적인 ID가 없다면 최후의 수단으로 목록의 인덱스를 key로 사용할 수 있습니다.

     

    항목의 순서가 바뀔 수 있는 경우 성능이 저하되거나 state 관련 문제가 발생할 수 있기 때문에 key에 인덱스를 사용하는 것은 권장하지 않습니다. 리스트 항목에 명시적으로 key를 지정하지 않으면 React는 기본적으로 인덱스를 key로 지정합니다.

     

     

    Key로 컴포넌트 추출하기

    key는 주변 배열의 context에서만 의미가 있습니다. map() 함수 내부에 있는 엘리먼트에 key를 넣어 주는 게 좋다고 합니다.

    function ListItem(props) {
        //여기에서 key를 넣는 것이 아니라
        return <li>{props.value}</li>;
    }
    
    function NumerList(props) {
        const numvers = props.numbers;
        const listItems = numbers.map((number) =>
            //여기에서 key를 사용!!!
            <ListItem key={number.toString} value={number} />
        );
        return (
            <ul>{listItems}</ul>
        );
    }

     

     

    Key는 형제 사이에서만 고유한 값이어야 한다.

    key는 배열 안에서 고유해야 하고 전체 범위에서 고유할 필요는 없습니다. 따라서 두 개의 배열을 만들 때 동일한 key를 사용할 수 있습니다.

    function Blog(props) {
        const sidebar = (
            <ul>
                {props.posts.map((post) =>
                    <li key={post.id}>
                        {post.title}
                    </li>
                )}
            </ul>
        );
        const content = props.posts.map((post) =>
            <div key={post.id}>
                <h3>{post.title}</h3>
                <p>{post.content}</p>
            </div>
        );
        return (
            <div>
                {sidebar}
                <hr />
                {content}
            </div>
        )
    }
    
    const posts = [
        {id: 1, title: 'Hello world', content: 'Welcome to learning React!'},
        {id: 2, title: 'Installation', content: 'You can install React from npm'}
    ]
    
    function ListAndKey() {
        return (
            <div>
                <Blog posts={posts} />
            </div>
        )
    }

    React에서 key는 힌트를 제공하지만 컴포넌트로 전달하지는 않습니다. 따라서 컴포넌트에서 key와 동일한 값이 필요하다면 다른 이름의 props로 명시적으로 전달해야 합니다.

    const content = props.map((post) =>
      <Post
        key={post.id}
        id={post.id}
        title={post.title} />
    );

    위의 코드에서 Post 컴포넌트는 props.id는 읽을 수 있지만 props.key는 읽을 수 없습니다.

     

     

    JSX에 map() 포함시키기

    위의 예시에서는 listItems 변수를 선언하고 JSX에 포함하였는데 JSX는 중괄호 안에 모든 표현식을 포함시킬 수 있으므로 map() 함수의 결과를 인라인으로 처리할 수 있습니다.

    function NumerList(props) {
        const numvers = props.numbers;
        return (
            <ul>
                {numbers.map((Number) =>
                    <ListItem key={number.toString} value={number} />
                )}
            </ul>
        );
    }

    가독성을 위해 변수로 추출할지 인라인으로 넣을지는 개발자의 재량입니다. map() 함수가 너무 중첩된다면 컴포넌트로 추출하는 것이 좋습니다.

    728x90

    댓글

Designed by Tistory.