[코낭] 6.3 key / 6.4 응용 / 7.1 라이프 사이클 메서드의 이해

최정윤·2023년 5월 31일
0

코낭

목록 보기
19/41

6.3 key

  • 리액트에서 key는 컴포넌트 배열을 렌더링했을 때 어떤 원소에 변동이 있었는지 알아내려고 사용한다.
  • key가 없을 때는 Virtual DOM을 비교하는 과정에서 리스트를 순차적으로 비교하면서 변화를 감지하지만 key가 있다면 이 값을 사용하여 어떤 변화가 일어났는지 더욱 빠르게 알아낼 수 있다.

6.3.1 key 설정

  • key 값을 설정할 때는 map 함수의 인자로 전달되는 함수 내부에서 컴포넌트 props를 설정하듯이 설정하면 된다.
  • key 값은 언제나 유일해야 한다.

  • key 설정 전에는 위 사진과 같이 "key" prop이 없다는 경고 메시지를 표시한다.

▶ IterationSample.js

const IterationsSample = () => {
    const names = ['눈사람', '얼음', '눈', '바람'];
    const nameList = names.map((name, index) => <li key={index}>{name}</li>);
    return <ul>{nameList}</ul>;
}

export default IterationsSample;
  • map함수에 전달되는 콜백 함수의 인수인 index값을 사용하여 고유 번호를 지정해준다.
  • 코드를 위와 같이 수정하면 더 이상 경고메시지가 뜨지 않는다.
  • index를 key로 사용하면 배열이 변경될 때 효율적으로 리렌더링하지 못하므로 고유값이 없을 때만 index 값을 key로 사용하도록 한다.

6.4 응용

  • 고윳값을 만들어 동적인 배열을 렌더링하는 것을 구현해보자.

6.4.1 초기 상태 설정하기

  • IterationSample 컴포넌트에서 useState를 사용하여 상태를 설정해보자.
  • 세 가지 상태 중에서 하나는 데이터 배열이고, 다른 하나는 텍스트를 입력할 수 있는 input의 상태, 마지막 하나는 데이터 배열에서 새로운 항목을 추가할 때 사용할 고유 id를 위한 상태이다.
  • 객체 형태로 이루어진 배열을 만들어보자.

▶ IterationSample.js

import {useState} from 'react';

const IterationsSample = () => {
    const [names, setNames] = useState([
        {id: 1, text: '눈사람'}, 
        {id: 2, text: '얼음'},
        {id: 3, text: '눈'},
        {id: 4, text: '바람'}
    ]);
    const [inputText, setInputText] = useState('');
    const [nextId, setNextId] = useState(5); // 새로운 항목을 추가할 때 사용할 id

    const nameList = names.map(name => <li key={name.id}>{name.text}</li>);
    return <ul>{nameList}</ul>;
};

export default IterationsSample;
  • map 함수를 사용할 때 key 값을 index 대신 name.id값으로 지정해 주었다.

6.4.2 데이터 추가 기능 구현하기

  • 새로운 이름을 등록할 수 있는 기능 구현
  • ul 태그 상단에 input과 button을 렌더링하고, input의 상태를 관리
  • 버튼을 클릭했을 때 호출할 onClick 함수를 선언하여 버튼의 onClick 이벤트로 설정
  • onClick 함수에서의 배열의 내장 함수 concat을 사용하여 새로운 항목을 추가한 배열을 만들고, setNames를 통해 상태 업데이트를 해준다.

▶ IterationSample.js

import {useState} from 'react';

const IterationsSample = () => {
    const [names, setNames] = useState([
        {id: 1, text: '눈사람'}, 
        {id: 2, text: '얼음'},
        {id: 3, text: '눈'},
        {id: 4, text: '바람'}
    ]);
    const [inputText, setInputText] = useState('');
    const [nextId, setNextId] = useState(5); // 새로운 항목을 추가할 때 사용할 id

    const onChange = e => setInputText(e.target.value);
    const onClick = () => {
        const nextNames = names.concat({
            id: nextId, //nextId 값을 id로 설정하고
            text: inputText
        });
        setNextId(nextId + 1); // nextId 값에 1을 더해 준다.
        setNames(nextNames); // names 값을 업데이트한다.
        setInputText(''); // inputText를 비운다.
    }

    const nameList = names.map(name => <li key={name.id}>{name.text}</li>);
    return (
        <>
            <input value={inputText} onChange={onChange} />
            <button onClick={onClick}>추가</button>
            <ul>{nameList}</ul>;
        </>
    );
};

export default IterationsSample;
  • push 함수는 기존 배열 자체를 변경해주지만, concat은 새로운 배열을 만들어 준다는 차이점이 있다.
  • 리액트에서 상태를 업데이트할 때는 기존 상태를 그대로 두면서 새로운 값을 상태로 설정해야 한다.
  • onClick 함수에서 새로운 항목을 추가할 때 객체의 id 값은 nextId를 사용하도록 하고, 클릭될 때마다 값이 1씩 올라가도록 구현한다.
  • button이 클릭될 때 기존의 input 내용을 비우는것도 구현해 준다.

  • input에 입력값을 입력하고 버튼을 누르면 새 항목이 추가된다.

6.4.3 데이터 제거 기능 구현하기

  • 각 항목을 더블클릭햇을 때 해당 항목이 사라지는 기능을 구현해 보는데 불변성을 유지하면서 배열의 특정 항목을 지울 때는 배열의 내장 함수 filter를 사용한다.
import {useState} from 'react';

const IterationsSample = () => {
    const [names, setNames] = useState([
        {id: 1, text: '눈사람'}, 
        {id: 2, text: '얼음'},
        {id: 3, text: '눈'},
        {id: 4, text: '바람'}
    ]);
    const [inputText, setInputText] = useState('');
    const [nextId, setNextId] = useState(5); // 새로운 항목을 추가할 때 사용할 id

    const onChange = e => setInputText(e.target.value);
    const onClick = () => {
        const nextNames = names.concat({
            id: nextId, //nextId 값을 id로 설정하고
            text: inputText,
        });
        setNextId(nextId + 1); // nextId 값에 1을 더해 준다.
        setNames(nextNames); // names 값을 업데이트한다.
        setInputText(''); // inputText를 비운다.
    };

    const onRemove = (id) => {
        const nextNames = names.filter((name) => name.id !== id);
        setNames(nextNames);
    };

    const nameList = names.map((name) => (
        <li key={name.id} onDoubleClick={() => onRemove(name.id)}>
            {name.text}
        </li>
    ));
    return (
        <>
            <input value={inputText} onChange={onChange} />
            <button onClick={onClick}>추가</button>
            <ul>{nameList}</ul>
        </>
    );
};

export default IterationsSample;

  • HTML요소를 더블클릭할 때 사용하는 이벤트의 이름은 onDoubleClick이다.
  • onRemove라는 함수를 구현해서 각 li 요소에 이벤트로 등록해 준다.
  • onRemove 함수에서는 클릭할 때 클릭이 발생한 li 요소의 id를 매개변수로 받아 해당 id를 가진 name 객체를 제거하고, 필터링 된 배열 nextNames로 names를 업데이트 한다.

정리

  • 배열을 변형할 때는 배열에 직접 접근하여 수정하는 것이 아니라 concat, filter등의 배열 내장 함수를 사용하여 새로운 배열을 만든 후 이를 새로운 상태로 설정해 주어야 한다는 점을 기억하자.

7. 컴포넌트의 라이프 사이클 메서드

  • 모든 리액트 컴포넌트에는 라이프 사이클(수명주기)이 존재한다.
  • 리액트 프로젝트를 진행하다 보면, 컴포넌트를 처음으로 렌더링 할 때 혹은 컴포넌트를 업데이트하기 전후로 어떤 작업을 처리해야 할 수도 있고, 불필요한 업데이트를 방지해야 할 때가 있는데 이때 컴포넌트의 라이프 사이클 메서드를 사용한다.

7.1 라이프사이클 메서드의 이해

  • 위 사진들은 컴포넌트의 라이프사이클이다.
  • 라이프사이클 메서드는 총 9가지이다.
  • Will 접두사 - 어떤 작업을 작동하기 전에 실행되는 메서드
  • Did 접두사 - 어떤 작업을 작동한 후에 실행되는 메서드
  • 위 메서드들은 컴포넌트 클래스에서 덮어서 선언함으로 사용할 수 있다.

마운트

  • DOM이 생성되고 웹 브라우저상에 컴포넌트가 나타나는 것을 마운트라고 한다.

  • 위 사진은 마운트 할 때 호출하는 메서드이다.
  1. constructor : 컴포넌트를 새로 만들 때마다 호출되는 클래스 생성자 메서드입니다.
  2. getDerivedStateFromProps 메서드 : props에 있는 값을 state에 넣을 때 사용하는 메서드
  3. render 메서드 : 준비한 UI를 렌더링 하는 메서드
    4 .componentDidMount 메서드 : 컴포넌트가 웹 브라우저상에 나타난 후에 호출하는 메서드

업데이트

  • 컴포넌트 정보를 업데이트(리렌더링) 한다.
  • 컴포넌트는 다음과 같은 총 네 가지 경우에 업데이트를 한다.
    • props가 바뀔 때
    • state가 바뀔 때
    • 부모 컴포넌트가 리렌더링될 때
    • this.forceUpdate로 강제로 렌더링을 트리거 할 때

  • 위 사진은 업데이트 할 때 호출하는 메서드이다.
  1. getDerivedStateFromProps 메서드 : props에 있는 값을 state에 넣을 때 사용하는 메서드(마운트에서도 호출됨)
  2. shiuldComponenetUpdate 메서드 : 컴포넌트가 리렌더링을 해야 할지 말아야 할지를 결정하는 메서드(true를 반환하면 리렌더링, false 면 리렌더링 하지 않음)
  3. render 메서드 : 준비한 UI를 렌더링 하는 메서드
  4. getSnapshotBeforeUpdate : 컴포넌트 변화를 DOM에 반영하기 직전에 호출하는 메서드
  5. componentDidUpdate : 컴포넌트의 업데이트 작업이 끝난 후 호출하는 이벤트

언마운트

  • 컴포넌트를 DOM에서 제거하는 것이다.

  • 위 사진은 언마운트 할 때 호출하는 메서드이다.
  1. componentWillUnmount : 컴포넌트가 웹 브라우저상에서 사라지기 전에 호출하는 메서드입니다.
profile
개발 기록장

0개의 댓글