[React] State

MinJi·2024년 8월 13일

FrontEnd

목록 보기
6/13

State

  • 컴포넌트의 기억 저장소
  • 컴포넌트 인스턴스에 지역적이다. 즉, 동일한 컴포넌트를 두 번 렌더링한다면 각 복사본은 완전히 격리된 state를 가진다.
  • 부모 컴포넌트는 자식 컴포넌트의 state를 변경할 수 없다. 따라서, 두 개의 컴포넌트의 state를 동기화 시키고 싶다면 자식 컴포넌트에서 state를 제거하고 가장 가까운 공통 부모 컴포넌트에 state를 추가해야한다.
  • 지역변수는 렌더링 간에 유지되지 않고 지역변수를 변경해도 렌더링을 일으키지 않는다. 따라서, 렌더링 사이에 데이터를 유지하고, React가 새로운 데이터로 컴포넌트를 렌더링하도록 해야한다.
    -> 이를 제공하는 것이 useState이다.
  1. state 변수는 렌더링 간에 데이터를 유지한다.
  2. state setter 함수는 변수를 업데이트하고 React가 컴포넌트를 다시 렌더링하도록 한다.

state 변수 추가하기

기존 코드

import { sculptureList } from './data.js';

export default function Gallery() {
  let index = 0;

  function handleClick() {
    index = index + 1;
  }

  let sculpture = sculptureList[index];
  return (
    <>
      <button onClick={handleClick}>
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i> 
        by {sculpture.artist}
      </h2>
      <h3>  
        ({index + 1} of {sculptureList.length})
      </h3>
      <img 
        src={sculpture.url} 
        alt={sculpture.alt}
      />
      <p>
        {sculpture.description}
      </p>
    </>
  );
}
  1. React에서 useState를 가져온다.
import { useState } from 'react';
  1. state 변수와 setter 함수를 지정한다.
// 기존 코드
let index = 0;
// 변경 코드
const [index, setIndex] = useState(0);
  1. setIndex를 이용한여 코드를 변경한다.
function handleClick() {
  setIndex(index + 1);
}

useState

  • useState와 같이 'use'로 시작하는 다른 모든 함수를 훅이라고 한다.
    - 훅은 React가 오직 렌더링 중일 때만 사용할 수 있는 특별한 함수 이다.
const [index, setIndex] = useState(0);
  • index의 초기값은 useState(0)에 의해 0으로 설정된다.
  • 컴포넌트가 렌더링 될 때마다, useState는 다음 두 개의 값을 포함하는 배열을 제공한다.
    1. 저장한 값을 가진 state 변수(=index)
    2. state 변수를 업데이트하고 React에 컴포넌트를 다시 렌더링하도록 유발하는 state setter 함수(=setIndex)
  • 작동 방식
  1. 컴포넌트가 처음 렌더링 된다. useState(0)은 [0, setIndex]를 반환하며, 0을 최신 state 값으로 기억한다.
  2. state를 업데이트한다. 사용자가 버튼을 클릭하면 setIndex(index + 1)을 호출하며, React는 index를 1로 기억한 상태로 다른 렌더링을 유발한다.
  3. 컴포넌트가 두 번째로 렌더링 된다. useState(0)을 보지만 index가 1로 기억되므로 [1, setIndex]를 반환한다.
  4. 반복

컴포넌트에 여러 state 변수 지정하기

  • 하나의 컴포넌트에 원하는 만큼 많은 타입의 state 변수를 가질 수 있다.
  • 서로 연관이 없는 경우 여러 개의 state 변수를 가지는 것이 좋고, 여러 state 변수를 자주 함께 변경하는 경우 변수를 하나로 합치는 것이 더 좋을 수 있다.

객체 State 업데이트하기

  • 객체를 업데이트하고 싶다면 새로운 객체를 생서하거나 기존 객체의 복사본을 만들어 state가 복사본을 사용하도록 해야 한다.

전개 문법으로 객체 복사하기

  • 종종 새로 생성하는 객체에 존재하는 데이터를 포함하고 싶을 때, '...' 객체 전개 구문을 사용하면 모든 프로퍼티를 각각 복사하지 않아도 된다.
  • '...' 전개 문법은 한 레벨 깊이의 내용만 복사한다.

배열 State 업데이트하기

  • 새 배열을 생성하거나 기존 배열의 복사본을 생성한 뒤, 새 배열을 state로 두어 업데이트 해야한다.
  • 배열 내부의 항목을 재할당해서는 안되며, 배열을 변경해서는 안된다.
  • filter()와 map() 같은 함수를 사용하여 원본 배열로부터 새 배열을 만든 후 state에 설정하여 업데이트할 수 있다.

배열에 항목 추가하기

  • '...' 배열 전개 구문을 사용한다.(앞 또는 뒤에 추가)
setArtists( // 아래의 새로운 배열로 state를 변경합니다.
  [
    ...artists, // 기존 배열의 모든 항목에,
    { id: nextId++, name: name } // 마지막에 새 항목을 추가합니다.
  ]
);

배열에 항목 제거하기

  • filter 함수를 사용한다.
setArtists(
  artists.filter(a => a.id !== artist.id)
);

배열 변환하기

  • 배열의 일부 또는 전체 항목을 변경하고자 한다면 map() 함수 사용해 새로운 배열을 만들 수 있다.
  • 배열에서 하나 이상의 항목을 교체하는 경우에도 map을 사용하는 것이 좋다.
function handleClick() {
    const nextShapes = shapes.map(shape => {
      if (shape.type === 'square') {
        // 변경시키지 않고 반환합니다.
        return shape;
      } else {
        // 50px 아래로 이동한 새로운 원을 반환합니다.
        return {
          ...shape,
          y: shape.y + 50,
        };
      }
    });
    // 새로운 배열로 리렌더링합니다.
    setShapes(nextShapes);
}

배열에 항목 삽입하기

  • 시작, 끝이 아닌 위치에 항목을 삽입하고 싶다면, '...' 배열 전개 구문과 slice() 함수를 함께 사용할 수 있다.
function handleClick() {
    const insertAt = 1; // 모든 인덱스가 될 수 있습니다.
    const nextArtists = [
      // 삽입 지점 이전 항목
      ...artists.slice(0, insertAt),
      // 새 항목
      { id: nextId++, name: name },
      // 삽입 지점 이후 항목
      ...artists.slice(insertAt)
    ];
    setArtists(nextArtists);
    setName('');
}

0개의 댓글