State: A Component's Memory

김동현·2026년 3월 15일

title: "State: 컴포넌트의 기억력 (A Component's Memory)"

안녕하세요! 프론트엔드 개발의 세계로 오신 것을 환영합니다. 오늘은 React에서 가장 중요하고 핵심적인 개념 중 하나인 State(상태) 에 대해 완벽하게 마스터해 볼 거예요. 공식 문서를 바탕으로 하나하나 꼼꼼하게, 하지만 아주 쉽게 풀어서 설명해 드릴게요. 자, 시작해 볼까요?

컴포넌트는 사용자와의 상호작용 결과로 화면에 보이는 내용을 변경해야 할 때가 정말 많아요. 예를 들어 폼(form)에 글자를 입력하면 입력 필드가 화면에 바로 업데이트되어야 하고, 이미지 슬라이드에서 "다음" 버튼을 클릭하면 표시되는 이미지가 바뀌어야 하죠. 또, "구매" 버튼을 클릭하면 상품이 장바구니에 담겨야 하고요.

이처럼 컴포넌트는 현재 입력값, 현재 이미지, 장바구니에 담긴 내역 같은 것들을 "기억" 해야 할 필요가 있습니다. React에서는 이런 컴포넌트별 고유한 메모리(기억력)를 바로 State(상태) 라고 부른답니다.

(💡 강사의 보충 설명: 프로그래밍에서 '상태'라고 하면 왠지 어렵게 느껴질 수 있는데요, 아주 쉽게 생각해서 '컴포넌트가 변화하는 데이터를 임시로 적어두는 전용 메모장' 이라고 생각하시면 이해하기 편하실 거예요!)

이번 장에서 배울 내용:

  • useState Hook을 사용해서 상태 변수를 추가하는 방법
  • useState Hook이 반환하는 두 가지 값의 짝(pair)이 무엇인지
  • 두 개 이상의 상태 변수를 추가하는 방법
  • 왜 State를 '지역적(local)'이라고 부르는지

일반 변수로는 충분하지 않을 때 {/when-a-regular-variable-isnt-enough/}

자, 여기 조각상 이미지를 보여주는 컴포넌트가 있어요. "Next(다음)" 버튼을 클릭하면 index1, 그 다음엔 2로 변경해서 다음 조각상을 보여주도록 의도한 코드입니다. 하지만 아래 코드는 제대로 작동하지 않아요 (직접 시도해 보세요!):

// {expectedErrors: {'react-compiler': [7]}}
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>
    </>
  );
}
// src/data.js
export const sculptureList = [{
  name: 'Homenaje a la Neurocirugía',
  artist: 'Marta Colvin Andrade',
  description: 'Although Colvin is predominantly known for abstract themes that allude to pre-Hispanic symbols, this gigantic sculpture, an homage to neurosurgery, is one of her most recognizable public art pieces.',
  url: '[https://i.imgur.com/Mx7dA2Y.jpg](https://i.imgur.com/Mx7dA2Y.jpg)',
  alt: 'A bronze statue of two crossed hands delicately holding a human brain in their fingertips.'  
}, {
  name: 'Floralis Genérica',
  artist: 'Eduardo Catalano',
  description: 'This enormous (75 ft. or 23m) silver flower is located in Buenos Aires. It is designed to move, closing its petals in the evening or when strong winds blow and opening them in the morning.',
  url: '[https://i.imgur.com/ZF6s192m.jpg](https://i.imgur.com/ZF6s192m.jpg)',
  alt: 'A gigantic metallic flower sculpture with reflective mirror-like petals and strong stamens.'
}, {
  name: 'Eternal Presence',
  artist: 'John Woodrow Wilson',
  description: 'Wilson was known for his preoccupation with equality, social justice, as well as the essential and spiritual qualities of humankind. This massive (7ft. or 2,13m) bronze represents what he described as "a symbolic Black presence infused with a sense of universal humanity."',
  url: '[https://i.imgur.com/aTtVpES.jpg](https://i.imgur.com/aTtVpES.jpg)',
  alt: 'The sculpture depicting a human head seems ever-present and solemn. It radiates calm and serenity.'
}, {
  name: 'Moai',
  artist: 'Unknown Artist',
  description: 'Located on the Easter Island, there are 1,000 moai, or extant monumental statues, created by the early Rapa Nui people, which some believe represented deified ancestors.',
  url: '[https://i.imgur.com/RCwLEoQm.jpg](https://i.imgur.com/RCwLEoQm.jpg)',
  alt: 'Three monumental stone busts with the heads that are disproportionately large with somber faces.'
}, {
  name: 'Blue Nana',
  artist: 'Niki de Saint Phalle',
  description: 'The Nanas are triumphant creatures, symbols of femininity and maternity. Initially, Saint Phalle used fabric and found objects for the Nanas, and later on introduced polyester to achieve a more vibrant effect.',
  url: '[https://i.imgur.com/Sd1AgUOm.jpg](https://i.imgur.com/Sd1AgUOm.jpg)',
  alt: 'A large mosaic sculpture of a whimsical dancing female figure in a colorful costume emanating joy.'
}, {
  name: 'Ultimate Form',
  artist: 'Barbara Hepworth',
  description: 'This abstract bronze sculpture is a part of The Family of Man series located at Yorkshire Sculpture Park. Hepworth chose not to create literal representations of the world but developed abstract forms inspired by people and landscapes.',
  url: '[https://i.imgur.com/2heNQDcm.jpg](https://i.imgur.com/2heNQDcm.jpg)',
  alt: 'A tall sculpture made of three elements stacked on each other reminding of a human figure.'
}, {
  name: 'Cavaliere',
  artist: 'Lamidi Olonade Fakeye',
  description: "Descended from four generations of woodcarvers, Fakeye's work blended traditional and contemporary Yoruba themes.",
  url: '[https://i.imgur.com/wIdGuZwm.png](https://i.imgur.com/wIdGuZwm.png)',
  alt: 'An intricate wood sculpture of a warrior with a focused face on a horse adorned with patterns.'
}, {
  name: 'Big Bellies',
  artist: 'Alina Szapocznikow',
  description: "Szapocznikow is known for her sculptures of the fragmented body as a metaphor for the fragility and impermanence of youth and beauty. This sculpture depicts two very realistic large bellies stacked on top of each other, each around five feet (1,5m) tall.",
  url: '[https://i.imgur.com/AlHTAdDm.jpg](https://i.imgur.com/AlHTAdDm.jpg)',
  alt: 'The sculpture reminds a cascade of folds, quite different from bellies in classical sculptures.'
}, {
  name: 'Terracotta Army',
  artist: 'Unknown Artist',
  description: 'The Terracotta Army is a collection of terracotta sculptures depicting the armies of Qin Shi Huang, the first Emperor of China. The army consisted of more than 8,000 soldiers, 130 chariots with 520 horses, and 150 cavalry horses.',
  url: '[https://i.imgur.com/HMFmH6m.jpg](https://i.imgur.com/HMFmH6m.jpg)',
  alt: '12 terracotta sculptures of solemn warriors, each with a unique facial expression and armor.'
}, {
  name: 'Lunar Landscape',
  artist: 'Louise Nevelson',
  description: 'Nevelson was known for scavenging objects from New York City debris, which she would later assemble into monumental constructions. In this one, she used disparate parts like a bedpost, juggling pin, and seat fragment, nailing and gluing them into boxes that reflect the influence of Cubism’s geometric abstraction of space and form.',
  url: '[https://i.imgur.com/rN7hY6om.jpg](https://i.imgur.com/rN7hY6om.jpg)',
  alt: 'A black matte sculpture where the individual elements are initially indistinguishable.'
}, {
  name: 'Aureole',
  artist: 'Ranjani Shettar',
  description: 'Shettar merges the traditional and the modern, the natural and the industrial. Her art focuses on the relationship between man and nature. Her work was described as compelling both abstractly and figuratively, gravity defying, and a "fine synthesis of unlikely materials."',
  url: '[https://i.imgur.com/okTpbHhm.jpg](https://i.imgur.com/okTpbHhm.jpg)',
  alt: 'A pale wire-like sculpture mounted on concrete wall and descending on the floor. It appears light.'
}, {
  name: 'Hippos',
  artist: 'Taipei Zoo',
  description: 'The Taipei Zoo commissioned a Hippo Square featuring submerged hippos at play.',
  url: '[https://i.imgur.com/6o5Vuyu.jpg](https://i.imgur.com/6o5Vuyu.jpg)',
  alt: 'A group of bronze hippo sculptures emerging from the sett sidewalk as if they were swimming.'
}];
h2 { margin-top: 10px; margin-bottom: 0; }
h3 {
  margin-top: 5px;
  font-weight: normal;
  font-size: 100%;
}
img { width: 120px; height: 120px; }
button {
  display: block;
  margin-top: 10px;
  margin-bottom: 10px;
}

handleClick 이벤트 핸들러가 지역 변수인 index를 업데이트하고 있는 건 맞습니다. 하지만 다음 두 가지 이유 때문에 이 변경 사항이 화면에 보이지 않아요:

  1. 지역 변수는 렌더링 간에 유지되지 않습니다. React가 이 컴포넌트를 두 번째로 렌더링할 때, React는 완전히 처음부터 다시 렌더링합니다. 즉, 이전에 지역 변수에 생겼던 변경 사항은 전혀 고려하지 않는다는 뜻이죠.
  2. 지역 변수를 변경한다고 해서 렌더링이 트리거되지는 않습니다. React는 새로운 데이터로 컴포넌트를 다시 렌더링해야 한다는 사실을 깨닫지 못합니다.

(💡 강사의 보충 설명: 조금 더 쉽게 설명해 볼게요. 일반 자바스크립트 변수인 let index = 0;은 화면을 다시 그리게 하는 '마법의 힘'이 없어요. 숫자가 내부적으로 1로 올랐어도, React에게 "화면 다시 그려줘!"라고 알려주지 않으면 우리가 보는 브라우저 화면은 절대 바뀌지 않는답니다.)

새로운 데이터로 컴포넌트를 업데이트하려면 다음 두 가지가 반드시 일어나야 합니다:

  1. 렌더링 사이에 데이터를 유지(Retain) 할 것.
  2. 새로운 데이터로 컴포넌트를 다시 렌더링하도록 React를 트리거(Trigger) 할 것 (리렌더링).

바로 이 역할을 완벽하게 수행하는 것이 useState Hook입니다. 이 녀석이 다음 두 가지를 제공해주거든요:

  1. 렌더링 사이에 데이터를 유지해 주는 상태 변수 (state variable).
  2. 변수를 업데이트하고 React가 컴포넌트를 다시 렌더링하도록 트리거하는 상태 설정 함수 (state setter function).

상태 변수 추가하기 {/adding-a-state-variable/}

상태 변수를 추가하려면, 먼저 파일 최상단에서 React로부터 useState를 불러와야(import) 합니다:

import { useState } from 'react';

그런 다음, 아래 줄을:

let index = 0;

다음과 같이 바꿔주세요:

const [index, setIndex] = useState(0);

여기서 index가 바로 상태 변수이고, setIndex가 상태를 변경해주는 설정 함수(setter function)입니다.

(💡 강사의 보충 설명: 여기서 사용된 [] 문법은 자바스크립트의 배열 구조 분해 할당(array destructuring)이라고 부르는 기술이에요. 배열 안에서 값을 쉽게 꺼내 읽을 수 있게 해주는 아주 유용한 문법이죠. useState가 반환하는 배열은 항상 정확히 두 개의 항목을 가지고 있답니다.)

이 두 개가 handleClick 함수 안에서 어떻게 협력하는지 볼까요?

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

이제 "Next" 버튼을 클릭하면 현재 조각상이 정상적으로 바뀌는 것을 볼 수 있습니다:

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

export default function Gallery() {
  const [index, setIndex] = useState(0);

  function handleClick() {
    setIndex(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>
    </>
  );
}
// src/data.js
export const sculptureList = [{
  name: 'Homenaje a la Neurocirugía',
  artist: 'Marta Colvin Andrade',
  description: 'Although Colvin is predominantly known for abstract themes that allude to pre-Hispanic symbols, this gigantic sculpture, an homage to neurosurgery, is one of her most recognizable public art pieces.',
  url: '[https://i.imgur.com/Mx7dA2Y.jpg](https://i.imgur.com/Mx7dA2Y.jpg)',
  alt: 'A bronze statue of two crossed hands delicately holding a human brain in their fingertips.'  
}, {
  name: 'Floralis Genérica',
  artist: 'Eduardo Catalano',
  description: 'This enormous (75 ft. or 23m) silver flower is located in Buenos Aires. It is designed to move, closing its petals in the evening or when strong winds blow and opening them in the morning.',
  url: '[https://i.imgur.com/ZF6s192m.jpg](https://i.imgur.com/ZF6s192m.jpg)',
  alt: 'A gigantic metallic flower sculpture with reflective mirror-like petals and strong stamens.'
}, {
  name: 'Eternal Presence',
  artist: 'John Woodrow Wilson',
  description: 'Wilson was known for his preoccupation with equality, social justice, as well as the essential and spiritual qualities of humankind. This massive (7ft. or 2,13m) bronze represents what he described as "a symbolic Black presence infused with a sense of universal humanity."',
  url: '[https://i.imgur.com/aTtVpES.jpg](https://i.imgur.com/aTtVpES.jpg)',
  alt: 'The sculpture depicting a human head seems ever-present and solemn. It radiates calm and serenity.'
}, {
  name: 'Moai',
  artist: 'Unknown Artist',
  description: 'Located on the Easter Island, there are 1,000 moai, or extant monumental statues, created by the early Rapa Nui people, which some believe represented deified ancestors.',
  url: '[https://i.imgur.com/RCwLEoQm.jpg](https://i.imgur.com/RCwLEoQm.jpg)',
  alt: 'Three monumental stone busts with the heads that are disproportionately large with somber faces.'
}, {
  name: 'Blue Nana',
  artist: 'Niki de Saint Phalle',
  description: 'The Nanas are triumphant creatures, symbols of femininity and maternity. Initially, Saint Phalle used fabric and found objects for the Nanas, and later on introduced polyester to achieve a more vibrant effect.',
  url: '[https://i.imgur.com/Sd1AgUOm.jpg](https://i.imgur.com/Sd1AgUOm.jpg)',
  alt: 'A large mosaic sculpture of a whimsical dancing female figure in a colorful costume emanating joy.'
}, {
  name: 'Ultimate Form',
  artist: 'Barbara Hepworth',
  description: 'This abstract bronze sculpture is a part of The Family of Man series located at Yorkshire Sculpture Park. Hepworth chose not to create literal representations of the world but developed abstract forms inspired by people and landscapes.',
  url: '[https://i.imgur.com/2heNQDcm.jpg](https://i.imgur.com/2heNQDcm.jpg)',
  alt: 'A tall sculpture made of three elements stacked on each other reminding of a human figure.'
}, {
  name: 'Cavaliere',
  artist: 'Lamidi Olonade Fakeye',
  description: "Descended from four generations of woodcarvers, Fakeye's work blended traditional and contemporary Yoruba themes.",
  url: '[https://i.imgur.com/wIdGuZwm.png](https://i.imgur.com/wIdGuZwm.png)',
  alt: 'An intricate wood sculpture of a warrior with a focused face on a horse adorned with patterns.'
}, {
  name: 'Big Bellies',
  artist: 'Alina Szapocznikow',
  description: "Szapocznikow is known for her sculptures of the fragmented body as a metaphor for the fragility and impermanence of youth and beauty. This sculpture depicts two very realistic large bellies stacked on top of each other, each around five feet (1,5m) tall.",
  url: '[https://i.imgur.com/AlHTAdDm.jpg](https://i.imgur.com/AlHTAdDm.jpg)',
  alt: 'The sculpture reminds a cascade of folds, quite different from bellies in classical sculptures.'
}, {
  name: 'Terracotta Army',
  artist: 'Unknown Artist',
  description: 'The Terracotta Army is a collection of terracotta sculptures depicting the armies of Qin Shi Huang, the first Emperor of China. The army consisted of more than 8,000 soldiers, 130 chariots with 520 horses, and 150 cavalry horses.',
  url: '[https://i.imgur.com/HMFmH6m.jpg](https://i.imgur.com/HMFmH6m.jpg)',
  alt: '12 terracotta sculptures of solemn warriors, each with a unique facial expression and armor.'
}, {
  name: 'Lunar Landscape',
  artist: 'Louise Nevelson',
  description: 'Nevelson was known for scavenging objects from New York City debris, which she would later assemble into monumental constructions. In this one, she used disparate parts like a bedpost, juggling pin, and seat fragment, nailing and gluing them into boxes that reflect the influence of Cubism’s geometric abstraction of space and form.',
  url: '[https://i.imgur.com/rN7hY6om.jpg](https://i.imgur.com/rN7hY6om.jpg)',
  alt: 'A black matte sculpture where the individual elements are initially indistinguishable.'
}, {
  name: 'Aureole',
  artist: 'Ranjani Shettar',
  description: 'Shettar merges the traditional and the modern, the natural and the industrial. Her art focuses on the relationship between man and nature. Her work was described as compelling both abstractly and figuratively, gravity defying, and a "fine synthesis of unlikely materials."',
  url: '[https://i.imgur.com/okTpbHhm.jpg](https://i.imgur.com/okTpbHhm.jpg)',
  alt: 'A pale wire-like sculpture mounted on concrete wall and descending on the floor. It appears light.'
}, {
  name: 'Hippos',
  artist: 'Taipei Zoo',
  description: 'The Taipei Zoo commissioned a Hippo Square featuring submerged hippos at play.',
  url: '[https://i.imgur.com/6o5Vuyu.jpg](https://i.imgur.com/6o5Vuyu.jpg)',
  alt: 'A group of bronze hippo sculptures emerging from the sett sidewalk as if they were swimming.'
}];
h2 { margin-top: 10px; margin-bottom: 0; }
h3 {
 margin-top: 5px;
 font-weight: normal;
 font-size: 100%;
}
img { width: 120px; height: 120px; }
button {
  display: block;
  margin-top: 10px;
  margin-bottom: 10px;
}

첫 번째 Hook 만나기 {/meet-your-first-hook/}

React에서 useState를 비롯해 이름이 "use"로 시작하는 모든 함수를 Hook(훅) 이라고 부릅니다.

Hooks은 오직 React가 렌더링하는 중에만 사용할 수 있는 아주 특별한 함수들입니다. (렌더링에 대해서는 다음 페이지에서 더 자세히 다룰 거예요!) 이 Hook들을 사용하면 React의 다양한 기능에 "연결(hook into)"할 수 있답니다.

State는 이런 기능 중 하나일 뿐이고요, 앞으로 다른 많은 Hook들도 만나보시게 될 거예요.

use로 시작하는 함수인 Hook은 반드시 컴포넌트의 최상위 레벨이나 여러분이 직접 만든 커스텀 Hook 안에서만 호출할 수 있습니다. 조건문(if), 반복문(for), 또는 중첩된 함수 안에서는 절대 Hook을 호출할 수 없어요! Hook은 비록 함수이긴 하지만, 컴포넌트가 필요로 하는 것들에 대한 무조건적인 선언이라고 생각하는 편이 이해하기 훨씬 쉽습니다. 파일 상단에서 모듈을 "import"하는 것처럼 컴포넌트의 최상단에서 React 기능들을 "use(사용)"한다고 생각하세요.

(💡 강사의 보충 설명: Hook을 조건문 안에 넣으면 React가 상태의 순서를 잃어버려서 에러가 발생해요! 무조건 컴포넌트 몸체의 제일 바깥쪽(최상단)에 가지런히 적어주셔야 합니다.)

useState 해부하기 {/anatomy-of-usestate/}

여러분이 useState를 호출한다는 것은 React에게 "이 컴포넌트가 무언가를 기억하길 원해!"라고 말하는 것과 같습니다:

const [index, setIndex] = useState(0);

이 예제의 경우, React가 index라는 값을 기억해 주기를 원한 것이죠.

이 짝(pair)의 이름을 지을 때는 const [something, setSomething]과 같이 짓는 것이 관례(convention)입니다. 원한다면 어떤 이름으로든 지을 수 있지만, 관례를 따르면 프로젝트 전반에 걸쳐 코드를 훨씬 이해하기 쉬워집니다.

useState에 전달하는 유일한 인자(argument)는 바로 상태 변수의 초깃값입니다. 이 예제에서는 useState(0)이라고 작성했으니 index의 초깃값이 0으로 설정된 것이죠.

여러분의 컴포넌트가 렌더링될 때마다, useState는 두 개의 값을 가진 배열을 제공합니다:

  1. 여러분이 저장했던 값을 가진 상태 변수 (여기서는 index).
  2. 이 상태 변수를 업데이트하고 React가 컴포넌트를 다시 렌더링하도록 트리거할 수 있는 상태 설정 함수 (여기서는 setIndex).

실제로 이 과정이 어떻게 동작하는지 순서대로 살펴볼까요?

const [index, setIndex] = useState(0);
  1. 컴포넌트가 첫 번째로 렌더링됩니다. 초깃값으로 0을 넘겼기 때문에 useState[0, setIndex]를 반환합니다. 이제 React는 최신 상태 값이 0이라는 걸 기억하고 있습니다.
  2. 상태를 업데이트합니다. 사용자가 버튼을 클릭하면 setIndex(index + 1)이 호출됩니다. 현재 index0이므로 setIndex(1)이 실행되겠죠. 이렇게 하면 React에게 "이제 index1이야"라고 알려주고, 다시 렌더링하도록 트리거합니다.
  3. 컴포넌트의 두 번째 렌더링이 일어납니다. 코드상에는 여전히 useState(0)이라고 적혀 있지만, React는 index1로 설정했다는 것을 기억하고 있기 때문에 이번에는 [1, setIndex]를 반환합니다.
  4. 이후 렌더링도 마찬가지 방식으로 진행됩니다!

컴포넌트에 여러 개의 상태 변수 부여하기 {/giving-a-component-multiple-state-variables/}

하나의 컴포넌트 안에 원하는 타입의 상태 변수를 얼마든지 원하는 만큼 가질 수 있습니다. 아래 컴포넌트는 숫자 타입인 index와, "Show details(세부 정보 보기)" 버튼을 클릭할 때마다 토글되는 불리언(boolean) 타입의 showMore, 이렇게 두 개의 상태 변수를 가지고 있어요:

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

export default function Gallery() {
  const [index, setIndex] = useState(0);
  const [showMore, setShowMore] = useState(false);

  function handleNextClick() {
    setIndex(index + 1);
  }

  function handleMoreClick() {
    setShowMore(!showMore);
  }

  let sculpture = sculptureList[index];
  return (
    <>
      <button onClick={handleNextClick}>
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i> 
        by {sculpture.artist}
      </h2>
      <h3>  
        ({index + 1} of {sculptureList.length})
      </h3>
      <button onClick={handleMoreClick}>
        {showMore ? 'Hide' : 'Show'} details
      </button>
      {showMore && <p>{sculpture.description}</p>}
      <img 
        src={sculpture.url} 
        alt={sculpture.alt}
      />
    </>
  );
}
// src/data.js
export const sculptureList = [{
  name: 'Homenaje a la Neurocirugía',
  artist: 'Marta Colvin Andrade',
  description: 'Although Colvin is predominantly known for abstract themes that allude to pre-Hispanic symbols, this gigantic sculpture, an homage to neurosurgery, is one of her most recognizable public art pieces.',
  url: '[https://i.imgur.com/Mx7dA2Y.jpg](https://i.imgur.com/Mx7dA2Y.jpg)',
  alt: 'A bronze statue of two crossed hands delicately holding a human brain in their fingertips.'  
}, {
  name: 'Floralis Genérica',
  artist: 'Eduardo Catalano',
  description: 'This enormous (75 ft. or 23m) silver flower is located in Buenos Aires. It is designed to move, closing its petals in the evening or when strong winds blow and opening them in the morning.',
  url: '[https://i.imgur.com/ZF6s192m.jpg](https://i.imgur.com/ZF6s192m.jpg)',
  alt: 'A gigantic metallic flower sculpture with reflective mirror-like petals and strong stamens.'
}, {
  name: 'Eternal Presence',
  artist: 'John Woodrow Wilson',
  description: 'Wilson was known for his preoccupation with equality, social justice, as well as the essential and spiritual qualities of humankind. This massive (7ft. or 2,13m) bronze represents what he described as "a symbolic Black presence infused with a sense of universal humanity."',
  url: '[https://i.imgur.com/aTtVpES.jpg](https://i.imgur.com/aTtVpES.jpg)',
  alt: 'The sculpture depicting a human head seems ever-present and solemn. It radiates calm and serenity.'
}, {
  name: 'Moai',
  artist: 'Unknown Artist',
  description: 'Located on the Easter Island, there are 1,000 moai, or extant monumental statues, created by the early Rapa Nui people, which some believe represented deified ancestors.',
  url: '[https://i.imgur.com/RCwLEoQm.jpg](https://i.imgur.com/RCwLEoQm.jpg)',
  alt: 'Three monumental stone busts with the heads that are disproportionately large with somber faces.'
}, {
  name: 'Blue Nana',
  artist: 'Niki de Saint Phalle',
  description: 'The Nanas are triumphant creatures, symbols of femininity and maternity. Initially, Saint Phalle used fabric and found objects for the Nanas, and later on introduced polyester to achieve a more vibrant effect.',
  url: '[https://i.imgur.com/Sd1AgUOm.jpg](https://i.imgur.com/Sd1AgUOm.jpg)',
  alt: 'A large mosaic sculpture of a whimsical dancing female figure in a colorful costume emanating joy.'
}, {
  name: 'Ultimate Form',
  artist: 'Barbara Hepworth',
  description: 'This abstract bronze sculpture is a part of The Family of Man series located at Yorkshire Sculpture Park. Hepworth chose not to create literal representations of the world but developed abstract forms inspired by people and landscapes.',
  url: '[https://i.imgur.com/2heNQDcm.jpg](https://i.imgur.com/2heNQDcm.jpg)',
  alt: 'A tall sculpture made of three elements stacked on each other reminding of a human figure.'
}, {
  name: 'Cavaliere',
  artist: 'Lamidi Olonade Fakeye',
  description: "Descended from four generations of woodcarvers, Fakeye's work blended traditional 초점 themes.",
  url: '[https://i.imgur.com/wIdGuZwm.png](https://i.imgur.com/wIdGuZwm.png)',
  alt: 'An intricate wood sculpture of a warrior with a focused face on a horse adorned with patterns.'
}, {
  name: 'Big Bellies',
  artist: 'Alina Szapocznikow',
  description: "Szapocznikow is known for her sculptures of the fragmented body as a metaphor for the fragility and impermanence of youth and beauty. This sculpture depicts two very realistic large bellies stacked on top of each other, each around five feet (1,5m) tall.",
  url: '[https://i.imgur.com/AlHTAdDm.jpg](https://i.imgur.com/AlHTAdDm.jpg)',
  alt: 'The sculpture reminds a cascade of folds, quite different from bellies in classical sculptures.'
}, {
  name: 'Terracotta Army',
  artist: 'Unknown Artist',
  description: 'The Terracotta Army is a collection of terracotta sculptures depicting the armies of Qin Shi Huang, the first Emperor of China. The army consisted of more than 8,000 soldiers, 130 chariots with 520 horses, and 150 cavalry horses.',
  url: '[https://i.imgur.com/HMFmH6m.jpg](https://i.imgur.com/HMFmH6m.jpg)',
  alt: '12 terracotta sculptures of solemn warriors, each with a unique facial expression and armor.'
}, {
  name: 'Lunar Landscape',
  artist: 'Louise Nevelson',
  description: 'Nevelson was known for scavenging objects from New York City debris, which she would later assemble into monumental constructions. In this one, she used disparate parts like a bedpost, juggling pin, and seat fragment, nailing and gluing them into boxes that reflect the influence of Cubism’s geometric abstraction of space and form.',
  url: '[https://i.imgur.com/rN7hY6om.jpg](https://i.imgur.com/rN7hY6om.jpg)',
  alt: 'A black matte sculpture where the individual elements are initially indistinguishable.'
}, {
  name: 'Aureole',
  artist: 'Ranjani Shettar',
  description: 'Shettar merges the traditional and the modern, the natural and the industrial. Her art focuses on the relationship between man and nature. Her work was described as compelling both abstractly and figuratively, gravity defying, and a "fine synthesis of unlikely materials."',
  url: '[https://i.imgur.com/okTpbHhm.jpg](https://i.imgur.com/okTpbHhm.jpg)',
  alt: 'A pale wire-like sculpture mounted on concrete wall and descending on the floor. It appears light.'
}, {
  name: 'Hippos',
  artist: 'Taipei Zoo',
  description: 'The Taipei Zoo commissioned a Hippo Square featuring submerged hippos at play.',
  url: '[https://i.imgur.com/6o5Vuyu.jpg](https://i.imgur.com/6o5Vuyu.jpg)',
  alt: 'A group of bronze hippo sculptures emerging from the sett sidewalk as if they were swimming.'
}];
h2 { margin-top: 10px; margin-bottom: 0; }
h3 {
 margin-top: 5px;
 font-weight: normal;
 font-size: 100%;
}
img { width: 120px; height: 120px; }
button {
  display: block;
  margin-top: 10px;
  margin-bottom: 10px;
}

이 예제의 indexshowMore처럼 서로의 상태가 연관되어 있지 않다면 여러 개의 상태 변수를 가지는 것이 좋은 방법입니다. 하지만 만약 두 개의 상태 변수를 항상 같이 변경하는 일이 잦다면, 그 둘을 하나로 합치는 것이 더 관리하기 편할 수도 있습니다. 예를 들어, 필드가 많은 폼(form)의 경우 필드마다 상태 변수를 만드는 것보다 객체를 담고 있는 단일 상태 변수를 만드는 것이 훨씬 편리하죠. 더 많은 팁을 얻으시려면 State 구조 선택하기 (Choosing the State Structure)를 읽어보세요!

React는 어떤 state를 반환해야 할지 어떻게 알까요? {/how-does-react-know-which-state-to-return/}

(💡 강사의 보충 설명: 이 부분은 초보자 분들이 정말 많이 헷갈려 하는 내용이에요. 자세히 읽어보시면 Hook의 마법 같은 동작 원리를 이해하는 데 큰 도움이 됩니다!)

useState를 호출할 때, "내가 지금 어떤 상태 변수를 부르고 있는지"에 대한 어떠한 정보도 useState로 전달하지 않는다는 점을 눈치채셨나요? useState로 넘기는 식별자(identifier) 같은 건 아예 없습니다. 그렇다면 useState는 도대체 어떤 상태 변수를 반환해야 하는지 어떻게 아는 걸까요? 여러분이 작성한 함수를 몰래 파싱(해석)하는 마법이라도 부리는 걸까요? 정답은 '아니오'입니다.

대신, Hook이 이런 간결한 문법을 사용할 수 있는 비결은 동일한 컴포넌트가 렌더링될 때마다 언제나 동일한 순서로 호출되는 것에 의존한다는 사실에 있습니다. 위에서 언급했던 규칙("Hook은 최상위 레벨에서만 호출하세요")을 잘 지킨다면 Hook은 항상 똑같은 순서로 호출되기 때문에 실전에서는 아주 잘 작동한답니다. 게다가 린터 플러그인(linter plugin)이 여러분이 저지를 수 있는 대부분의 실수를 잡아주기도 하고요.

내부적으로 React는 각 컴포넌트마다 상태 짝(state pairs)들의 배열을 가지고 있습니다. 또한 렌더링을 시작하기 전에 0으로 설정되는 현재 짝의 인덱스(순서)도 유지하고 있죠. 여러분이 useState를 호출할 때마다, React는 다음 상태 짝을 여러분에게 건네주고 이 인덱스를 1씩 증가시킵니다. 이 메커니즘에 대해 더 깊이 알고 싶다면 React Hooks: Not Magic, Just Arrays. 글을 읽어보시는 것도 좋습니다.

아래 예제는 실제 React를 사용한 코드는 아니지만, 내부적으로 useState가 어떻게 동작하는지 감을 잡을 수 있게 해줍니다:

// src/index.js active
let componentHooks = [];
let currentHookIndex = 0;

// React 내부에서 useState가 동작하는 방식 (단순화된 버전).
function useState(initialState) {
  let pair = componentHooks[currentHookIndex];
  if (pair) {
    // 첫 번째 렌더링이 아니므로,
    // 상태 짝이 이미 존재합니다.
    // 그것을 반환하고 다음 Hook 호출을 위해 준비합니다.
    currentHookIndex++;
    return pair;
  }

  // 이번이 첫 번째 렌더링이므로,
  // 상태 짝을 만들고 저장합니다.
  pair = [initialState, setState];

  function setState(nextState) {
    // 사용자가 상태 변경을 요청하면,
    // 새로운 값을 짝에 넣습니다.
    pair[0] = nextState;
    updateDOM();
  }

  // 다음 렌더링을 위해 짝을 저장해두고
  // 다음 Hook 호출을 준비합니다.
  componentHooks[currentHookIndex] = pair;
  currentHookIndex++;
  return pair;
}

function Gallery() {
  // useState()가 호출될 때마다 다음 짝을 가져옵니다.
  const [index, setIndex] = useState(0);
  const [showMore, setShowMore] = useState(false);

  function handleNextClick() {
    setIndex(index + 1);
  }

  function handleMoreClick() {
    setShowMore(!showMore);
  }

  let sculpture = sculptureList[index];
  // 이 예제는 실제 React를 사용하지 않으므로,
  // JSX 대신 출력 객체를 반환합니다.
  return {
    onNextClick: handleNextClick,
    onMoreClick: handleMoreClick,
    header: `${sculpture.name} by ${sculpture.artist}`,
    counter: `${index + 1} of ${sculptureList.length}`,
    more: `${showMore ? 'Hide' : 'Show'} details`,
    description: showMore ? sculpture.description : null,
    imageSrc: sculpture.url,
    imageAlt: sculpture.alt
  };
}

function updateDOM() {
  // 컴포넌트를 렌더링하기 전에 
  // 현재 Hook 인덱스를 초기화합니다.
  currentHookIndex = 0;
  let output = Gallery();

  // 결과물에 맞춰 DOM을 업데이트합니다.
  // 이 부분이 바로 React가 여러분을 위해 대신 해주는 작업입니다.
  nextButton.onclick = output.onNextClick;
  header.textContent = output.header;
  moreButton.onclick = output.onMoreClick;
  moreButton.textContent = output.more;
  image.src = output.imageSrc;
  image.alt = output.imageAlt;
  if (output.description !== null) {
    description.textContent = output.description;
    description.style.display = '';
  } else {
    description.style.display = 'none';
  }
}

let nextButton = document.getElementById('nextButton');
let header = document.getElementById('header');
let moreButton = document.getElementById('moreButton');
let description = document.getElementById('description');
let image = document.getElementById('image');
let sculptureList = [{
  name: 'Homenaje a la Neurocirugía',
  artist: 'Marta Colvin Andrade',
  description: 'Although Colvin is predominantly known for abstract themes that allude to pre-Hispanic symbols, this gigantic sculpture, an homage to neurosurgery, is one of her most recognizable public art pieces.',
  url: '[https://i.imgur.com/Mx7dA2Y.jpg](https://i.imgur.com/Mx7dA2Y.jpg)',
  alt: 'A bronze statue of two crossed hands delicately holding a human brain in their fingertips.'  
}, {
  name: 'Floralis Genérica',
  artist: 'Eduardo Catalano',
  description: 'This enormous (75 ft. or 23m) silver flower is located in Buenos Aires. It is designed to move, closing its petals in the evening or when strong winds blow and opening them in the morning.',
  url: '[https://i.imgur.com/ZF6s192m.jpg](https://i.imgur.com/ZF6s192m.jpg)',
  alt: 'A gigantic metallic flower sculpture with reflective mirror-like petals and strong stamens.'
}, {
  name: 'Eternal Presence',
  artist: 'John Woodrow Wilson',
  description: 'Wilson was known for his preoccupation with equality, social justice, as well as the essential and spiritual qualities of humankind. This massive (7ft. or 2,13m) bronze represents what he described as "a symbolic Black presence infused with a sense of universal humanity."',
  url: '[https://i.imgur.com/aTtVpES.jpg](https://i.imgur.com/aTtVpES.jpg)',
  alt: 'The sculpture depicting a human head seems ever-present and solemn. It radiates calm and serenity.'
}, {
  name: 'Moai',
  artist: 'Unknown Artist',
  description: 'Located on the Easter Island, there are 1,000 moai, or extant monumental statues, created by the early Rapa Nui people, which some believe represented deified ancestors.',
  url: '[https://i.imgur.com/RCwLEoQm.jpg](https://i.imgur.com/RCwLEoQm.jpg)',
  alt: 'Three monumental stone busts with the heads that are disproportionately large with somber faces.'
}, {
  name: 'Blue Nana',
  artist: 'Niki de Saint Phalle',
  description: 'The Nanas are triumphant creatures, symbols of femininity and maternity. Initially, Saint Phalle used fabric and found objects for the Nanas, and later on introduced polyester to achieve a more vibrant effect.',
  url: '[https://i.imgur.com/Sd1AgUOm.jpg](https://i.imgur.com/Sd1AgUOm.jpg)',
  alt: 'A large mosaic sculpture of a whimsical dancing female figure in a colorful costume emanating joy.'
}, {
  name: 'Ultimate Form',
  artist: 'Barbara Hepworth',
  description: 'This abstract bronze sculpture is a part of The Family of Man series located at Yorkshire Sculpture Park. Hepworth chose not to create literal representations of the world but developed abstract forms inspired by people and landscapes.',
  url: '[https://i.imgur.com/2heNQDcm.jpg](https://i.imgur.com/2heNQDcm.jpg)',
  alt: 'A tall sculpture made of three elements stacked on each other reminding of a human figure.'
}, {
  name: 'Cavaliere',
  artist: 'Lamidi Olonade Fakeye',
  description: "Descended from four generations of woodcarvers, Fakeye's work blended traditional and contemporary Yoruba themes.",
  url: '[https://i.imgur.com/wIdGuZwm.png](https://i.imgur.com/wIdGuZwm.png)',
  alt: 'An intricate wood sculpture of a warrior with a focused face on a horse adorned with patterns.'
}, {
  name: 'Big Bellies',
  artist: 'Alina Szapocznikow',
  description: "Szapocznikow is known for her sculptures of the fragmented body as a metaphor for the fragility and impermanence of youth and beauty. This sculpture depicts two very realistic large bellies stacked on top of each other, each around five feet (1,5m) tall.",
  url: '[https://i.imgur.com/AlHTAdDm.jpg](https://i.imgur.com/AlHTAdDm.jpg)',
  alt: 'The sculpture reminds a cascade of folds, quite different from bellies in classical sculptures.'
}, {
  name: 'Terracotta Army',
  artist: 'Unknown Artist',
  description: 'The Terracotta Army is a collection of terracotta sculptures depicting the armies of Qin Shi Huang, the first Emperor of China. The army consisted of more than 8,000 soldiers, 130 chariots with 520 horses, and 150 cavalry horses.',
  url: '[https://i.imgur.com/HMFmH6m.jpg](https://i.imgur.com/HMFmH6m.jpg)',
  alt: '12 terracotta sculptures of solemn warriors, each with a unique facial expression and armor.'
}, {
  name: 'Lunar Landscape',
  artist: 'Louise Nevelson',
  description: 'Nevelson was known for scavenging objects from New York City debris, which she would later assemble into monumental constructions. In this one, she used disparate parts like a bedpost, juggling pin, and seat fragment, nailing and gluing them into boxes that reflect the influence of Cubism’s geometric abstraction of space and form.',
  url: '[https://i.imgur.com/rN7hY6om.jpg](https://i.imgur.com/rN7hY6om.jpg)',
  alt: 'A black matte sculpture where the individual elements are initially indistinguishable.'
}, {
  name: 'Aureole',
  artist: 'Ranjani Shettar',
  description: 'Shettar merges the traditional and the modern, the natural and the industrial. Her art focuses on the relationship between man and nature. Her work was described as compelling both abstractly and figuratively, gravity defying, and a "fine synthesis of unlikely materials."',
  url: '[https://i.imgur.com/okTpbHhm.jpg](https://i.imgur.com/okTpbHhm.jpg)',
  alt: 'A pale wire-like sculpture mounted on concrete wall and descending on the floor. It appears light.'
}, {
  name: 'Hippos',
  artist: 'Taipei Zoo',
  description: 'The Taipei Zoo commissioned a Hippo Square featuring submerged hippos at play.',
  url: '[https://i.imgur.com/6o5Vuyu.jpg](https://i.imgur.com/6o5Vuyu.jpg)',
  alt: 'A group of bronze hippo sculptures emerging from the sett sidewalk as if they were swimming.'
}];

// 초기 상태에 맞춰 UI를 구성합니다.
updateDOM();
<button id="nextButton">
  Next
</button>
<h3 id="header"></h3>
<button id="moreButton"></button>
<p id="description"></p>
<img id="image">

<style>
* { box-sizing: border-box; }
body { font-family: sans-serif; margin: 20px; padding: 0; }
button { display: block; margin-bottom: 10px; }
</style>
button { display: block; margin-bottom: 10px; }

이 내용을 완벽하게 다 이해하지 않아도 React를 사용하는 데는 아무런 지장이 없지만, 이 멘탈 모델(mental model)을 알고 있으면 나중에 아주 큰 도움이 될 거예요!

State는 격리되어 있고 프라이빗합니다 {/state-is-isolated-and-private/}

State는 화면 상의 컴포넌트 인스턴스마다 지역적(local)으로 존재합니다. 다시 말해서, 같은 컴포넌트를 두 번 렌더링하면 각각의 복사본은 완전히 독립된, 서로 격리된 State를 갖게 됩니다! 하나를 변경해도 다른 쪽에는 전혀 영향을 주지 않아요.

이 예제에서는 이전에 만들었던 Gallery 컴포넌트 내부 로직을 단 한 줄도 바꾸지 않고 두 번 렌더링했습니다. 두 갤러리 안에 있는 버튼들을 각각 클릭해 보세요. 이들의 상태가 얼마나 독립적인지 확인할 수 있을 거예요:

// src/App.js (or similar root file)
import Gallery from './Gallery.js';

export default function Page() {
  return (
    <div className="Page">
      <Gallery />
      <Gallery />
    </div>
  );
}
// src/Gallery.js
import { useState } from 'react';
import { sculptureList } from './data.js';

export default function Gallery() {
  const [index, setIndex] = useState(0);
  const [showMore, setShowMore] = useState(false);

  function handleNextClick() {
    setIndex(index + 1);
  }

  function handleMoreClick() {
    setShowMore(!showMore);
  }

  let sculpture = sculptureList[index];
  return (
    <section>
      <button onClick={handleNextClick}>
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i> 
        by {sculpture.artist}
      </h2>
      <h3>  
        ({index + 1} of {sculptureList.length})
      </h3>
      <button onClick={handleMoreClick}>
        {showMore ? 'Hide' : 'Show'} details
      </button>
      {showMore && <p>{sculpture.description}</p>}
      <img 
        src={sculpture.url} 
        alt={sculpture.alt}
      />
    </section>
  );
}
// src/data.js
export const sculptureList = [{
  name: 'Homenaje a la Neurocirugía',
  artist: 'Marta Colvin Andrade',
  description: 'Although Colvin is predominantly known for abstract themes that allude to pre-Hispanic symbols, this gigantic sculpture, an homage to neurosurgery, is one of her most recognizable public art pieces.',
  url: '[https://i.imgur.com/Mx7dA2Y.jpg](https://i.imgur.com/Mx7dA2Y.jpg)',
  alt: 'A bronze statue of two crossed hands delicately holding a human brain in their fingertips.'  
}, {
  name: 'Floralis Genérica',
  artist: 'Eduardo Catalano',
  description: 'This enormous (75 ft. or 23m) silver flower is located in Buenos Aires. It is designed to move, closing its petals in the evening or when strong winds blow and opening them in the morning.',
  url: '[https://i.imgur.com/ZF6s192m.jpg](https://i.imgur.com/ZF6s192m.jpg)',
  alt: 'A gigantic metallic flower sculpture with reflective mirror-like petals and strong stamens.'
}, {
  name: 'Eternal Presence',
  artist: 'John Woodrow Wilson',
  description: 'Wilson was known for his preoccupation with equality, social justice, as well as the essential and spiritual qualities of humankind. This massive (7ft. or 2,13m) bronze represents what he described as "a symbolic Black presence infused with a sense of universal humanity."',
  url: '[https://i.imgur.com/aTtVpES.jpg](https://i.imgur.com/aTtVpES.jpg)',
  alt: 'The sculpture depicting a human head seems ever-present and solemn. It radiates calm and serenity.'
}, {
  name: 'Moai',
  artist: 'Unknown Artist',
  description: 'Located on the Easter Island, there are 1,000 moai, or extant monumental statues, created by the early Rapa Nui people, which some believe represented deified ancestors.',
  url: '[https://i.imgur.com/RCwLEoQm.jpg](https://i.imgur.com/RCwLEoQm.jpg)',
  alt: 'Three monumental stone busts with the heads that are disproportionately large with somber faces.'
}, {
  name: 'Blue Nana',
  artist: 'Niki de Saint Phalle',
  description: 'The Nanas are triumphant creatures, symbols of femininity and maternity. Initially, Saint Phalle used fabric and found objects for the Nanas, and later on introduced polyester to achieve a more vibrant effect.',
  url: '[https://i.imgur.com/Sd1AgUOm.jpg](https://i.imgur.com/Sd1AgUOm.jpg)',
  alt: 'A large mosaic sculpture of a whimsical dancing female figure in a colorful costume emanating joy.'
}, {
  name: 'Ultimate Form',
  artist: 'Barbara Hepworth',
  description: 'This abstract bronze sculpture is a part of The Family of Man series located at Yorkshire Sculpture Park. Hepworth chose not to create literal representations of the world but developed abstract forms inspired by people and landscapes.',
  url: '[https://i.imgur.com/2heNQDcm.jpg](https://i.imgur.com/2heNQDcm.jpg)',
  alt: 'A tall sculpture made of three elements stacked on each other reminding of a human figure.'
}, {
  name: 'Cavaliere',
  artist: 'Lamidi Olonade Fakeye',
  description: "Descended from four generations of woodcarvers, Fakeye's work blended traditional and contemporary Yoruba themes.",
  url: '[https://i.imgur.com/wIdGuZwm.png](https://i.imgur.com/wIdGuZwm.png)',
  alt: 'An intricate wood sculpture of a warrior with a focused face on a horse adorned with patterns.'
}, {
  name: 'Big Bellies',
  artist: 'Alina Szapocznikow',
  description: "Szapocznikow is known for her sculptures of the fragmented body as a metaphor for the fragility and impermanence of youth and beauty. This sculpture depicts two very realistic large bellies stacked on top of each other, each around five feet (1,5m) tall.",
  url: '[https://i.imgur.com/AlHTAdDm.jpg](https://i.imgur.com/AlHTAdDm.jpg)',
  alt: 'The sculpture reminds a cascade of folds, quite different from bellies in classical sculptures.'
}, {
  name: 'Terracotta Army',
  artist: 'Unknown Artist',
  description: 'The Terracotta Army is a collection of terracotta sculptures depicting the armies of Qin Shi Huang, the first Emperor of China. The army consisted of more than 8,000 soldiers, 130 chariots 기병대, and 150 cavalry horses.',
  url: '[https://i.imgur.com/HMFmH6m.jpg](https://i.imgur.com/HMFmH6m.jpg)',
  alt: '12 terracotta sculptures of solemn warriors, each with a unique facial expression and armor.'
}, {
  name: 'Lunar Landscape',
  artist: 'Louise Nevelson',
  description: 'Nevelson was known for scavenging objects from New York City debris, which she would later assemble into monumental constructions. In this one, she used disparate parts like a bedpost, juggling pin, and seat fragment, nailing and gluing them into boxes that reflect the influence of Cubism’s geometric abstraction of space and form.',
  url: '[https://i.imgur.com/rN7hY6om.jpg](https://i.imgur.com/rN7hY6om.jpg)',
  alt: 'A black matte sculpture where the individual elements are initially indistinguishable.'
}, {
  name: 'Aureole',
  artist: 'Ranjani Shettar',
  description: 'Shettar merges the traditional and the modern, the natural and the industrial. Her art focuses on the relationship between man and nature. Her work was described as compelling both abstractly and figuratively, gravity defying, and a "fine synthesis of unlikely materials."',
  url: '[https://i.imgur.com/okTpbHhm.jpg](https://i.imgur.com/okTpbHhm.jpg)',
  alt: 'A pale wire-like sculpture mounted on concrete wall and descending on the floor. It appears light.'
}, {
  name: 'Hippos',
  artist: 'Taipei Zoo',
  description: 'The Taipei Zoo commissioned a Hippo Square featuring submerged hippos at play.',
  url: '[https://i.imgur.com/6o5Vuyu.jpg](https://i.imgur.com/6o5Vuyu.jpg)',
  alt: 'A group of bronze hippo sculptures emerging from the sett sidewalk as if they were swimming.'
}];
button { display: block; margin-bottom: 10px; }
.Page > * {
  float: left;
  width: 50%;
  padding: 10px;
}
h2 { margin-top: 10px; margin-bottom: 0; }
h3 {
  margin-top: 5px;
  font-weight: normal;
  font-size: 100%;
}
img { width: 120px; height: 120px; }
button {
  display: block;
  margin-top: 10px;
  margin-bottom: 10px;
}

바로 이것이 모듈 상단에 선언할 수 있는 일반 변수들과 State의 큰 차이점입니다. State는 특정한 함수 호출이나 코드 상의 특정 위치에 종속되어 있는 것이 아니라, 화면 상의 특정한 '위치(place)'에 지역적으로(local) 묶여 있어요. 지금 여러분이 <Gallery /> 컴포넌트를 두 번 렌더링했기 때문에 두 갤러리의 State는 서로 완전히 분리되어 저장되는 거랍니다.

또한, Page 컴포넌트가 Gallery의 상태에 대해 아무것도 "모른다"는 점에 주목해 보세요! 심지어 상태가 존재하는지조차 모릅니다. props와 달리, State는 그것을 선언한 컴포넌트에게 온전히 프라이빗(private)한 데이터입니다. 부모 컴포넌트는 이를 함부로 변경할 수 없어요. 덕분에 나머지 컴포넌트들에 아무런 영향을 주지 않고도 어떤 컴포넌트에든 자유롭게 상태를 추가하거나 제거할 수 있습니다.

그럼, 만약 두 갤러리 컴포넌트의 상태를 똑같이 동기화하고 싶다면 어떻게 해야 할까요? React에서 권장하는 올바른 방법은, 자식 컴포넌트들로부터 상태를 제거하고 그들과 가장 가까운 공유 부모 컴포넌트에 상태를 추가하는 것입니다. 앞으로 몇 페이지에 걸쳐서는 단일 컴포넌트의 상태를 구성하는 방법에 집중할 텐데, 이 주제는 나중에 컴포넌트 간에 State 공유하기 (Sharing State Between Components)에서 다시 다룰 예정이니 기대해 주세요!

요약해 볼까요?

  • 컴포넌트가 렌더링 사이에 어떤 정보를 "기억"해야 할 때는 상태 변수를 사용하세요.
  • 상태 변수는 useState Hook을 호출하여 선언합니다.
  • Hook은 use로 시작하는 아주 특별한 함수입니다. Hook을 사용하면 State 같은 React 기능에 "연결(hook into)"할 수 있어요.
  • Hook은 약간 import 구문과 비슷하다고 생각하시면 편해요. 반드시 무조건적으로 호출되어야만 하거든요. useState를 포함한 모든 Hook의 호출은 오직 컴포넌트나 다른 커스텀 Hook의 최상위 레벨에서만 유효합니다.
  • useState Hook은 두 개의 값이 든 짝(pair)을 반환합니다: 현재 상태값, 그리고 상태를 업데이트할 수 있는 함수.
  • 여러 개의 상태 변수를 가지는 것도 가능합니다. React 내부에서는 이 변수들을 호출된 순서를 기준으로 짝을 맞춥니다.
  • State는 컴포넌트에게 프라이빗한 데이터입니다. 같은 컴포넌트를 두 곳에서 렌더링하면, 각각의 복사본은 서로 다른 독립적인 State를 갖게 됩니다.

(💡 강사의 과제 안내: 직접 문제를 풀어보시길 권장드려요! 코딩 실력은 직접 손으로 쳐볼 때 가장 많이 늡니다.)

마지막 조각상에서 "Next" 버튼을 누르면 코드가 크래시(충돌)하면서 앱이 다운됩니다. 크래시를 방지할 수 있도록 로직을 고쳐보세요. 이벤트 핸들러 안에 추가적인 로직을 넣거나, 불가능한 동작일 경우 아예 버튼을 비활성화(disable)하는 방식으로 해결하실 수 있습니다.

충돌을 해결한 뒤에는, 이전 조각상을 보여주는 "Previous(이전)" 버튼을 추가해 보세요. 이 버튼 역시 첫 번째 조각상에서 클릭했을 때 충돌이 일어나서는 안 됩니다.

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

export default function Gallery() {
  const [index, setIndex] = useState(0);
  const [showMore, setShowMore] = useState(false);

  function handleNextClick() {
    setIndex(index + 1);
  }

  function handleMoreClick() {
    setShowMore(!showMore);
  }

  let sculpture = sculptureList[index];
  return (
    <>
      <button onClick={handleNextClick}>
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i> 
        by {sculpture.artist}
      </h2>
      <h3>  
        ({index + 1} of {sculptureList.length})
      </h3>
      <button onClick={handleMoreClick}>
        {showMore ? 'Hide' : 'Show'} details
      </button>
      {showMore && <p>{sculpture.description}</p>}
      <img 
        src={sculpture.url} 
        alt={sculpture.alt}
      />
    </>
  );
}
// src/data.js
export const sculptureList = [{
  name: 'Homenaje a la Neurocirugía',
  artist: 'Marta Colvin Andrade',
  description: 'Although Colvin is predominantly known for abstract themes that allude to pre-Hispanic symbols, this gigantic sculpture, an homage to neurosurgery, is one of her most recognizable public art pieces.',
  url: '[https://i.imgur.com/Mx7dA2Y.jpg](https://i.imgur.com/Mx7dA2Y.jpg)',
  alt: 'A bronze statue of two crossed hands delicately holding a human brain in their fingertips.'  
}, {
  name: 'Floralis Genérica',
  artist: 'Eduardo Catalano',
  description: 'This enormous (75 ft. or 23m) silver flower is located in Buenos Aires. It is designed to move, closing its petals in the evening or when strong winds blow and opening them in the morning.',
  url: '[https://i.imgur.com/ZF6s192m.jpg](https://i.imgur.com/ZF6s192m.jpg)',
  alt: 'A gigantic metallic flower sculpture with reflective mirror-like petals and strong stamens.'
}, {
  name: 'Eternal Presence',
  artist: 'John Woodrow Wilson',
  description: 'Wilson was known for his preoccupation with equality, social justice, as well as the essential and spiritual qualities of humankind. This massive (7ft. or 2,13m) bronze represents what he described as "a symbolic Black presence infused with a sense of universal humanity."',
  url: '[https://i.imgur.com/aTtVpES.jpg](https://i.imgur.com/aTtVpES.jpg)',
  alt: 'The sculpture depicting a human head seems ever-present and solemn. It radiates calm and serenity.'
}, {
  name: 'Moai',
  artist: 'Unknown Artist',
  description: 'Located on the Easter Island, there are 1,000 moai, or extant monumental statues, created by the early Rapa Nui people, which some believe represented deified ancestors.',
  url: '[https://i.imgur.com/RCwLEoQm.jpg](https://i.imgur.com/RCwLEoQm.jpg)',
  alt: 'Three monumental stone busts with the heads that are disproportionately large with somber faces.'
}, {
  name: 'Blue Nana',
  artist: 'Niki de Saint Phalle',
  description: 'The Nanas are triumphant creatures, symbols of femininity and maternity. Initially, Saint Phalle used fabric and found objects for the Nanas, and later on introduced polyester to achieve a more vibrant effect.',
  url: '[https://i.imgur.com/Sd1AgUOm.jpg](https://i.imgur.com/Sd1AgUOm.jpg)',
  alt: 'A large mosaic sculpture of a whimsical dancing female figure in a colorful costume emanating joy.'
}, {
  name: 'Ultimate Form',
  artist: 'Barbara Hepworth',
  description: 'This abstract bronze sculpture is a part of The Family of Man series located at Yorkshire Sculpture Park. Hepworth chose not to create literal representations of the world but developed abstract forms inspired by people and landscapes.',
  url: '[https://i.imgur.com/2heNQDcm.jpg](https://i.imgur.com/2heNQDcm.jpg)',
  alt: 'A tall sculpture made of three elements stacked on each other reminding of a human figure.'
}, {
  name: 'Cavaliere',
  artist: 'Lamidi Olonade Fakeye',
  description: "Descended from four generations of woodcarvers, Fakeye's work blended traditional and contemporary Yoruba themes.",
  url: '[https://i.imgur.com/wIdGuZwm.png](https://i.imgur.com/wIdGuZwm.png)',
  alt: 'An intricate wood sculpture of a warrior with a focused face on a horse adorned with patterns.'
}, {
  name: 'Big Bellies',
  artist: 'Alina Szapocznikow',
  description: "Szapocznikow is known for her sculptures of the fragmented body as a metaphor for the fragility and impermanence of youth and beauty. This sculpture depicts two very realistic large bellies stacked on top of each other, each around five feet (1,5m) tall.",
  url: '[https://i.imgur.com/AlHTAdDm.jpg](https://i.imgur.com/AlHTAdDm.jpg)',
  alt: 'The sculpture reminds a cascade of folds, quite different from bellies in classical sculptures.'
}, {
  name: 'Terracotta Army',
  artist: 'Unknown Artist',
  description: 'The Terracotta Army is a collection of terracotta sculptures depicting the armies of Qin Shi Huang, the first Emperor of China. The army consisted of more than 8,000 soldiers, 130 chariots with 520 horses, and 150 cavalry horses.',
  url: '[https://i.imgur.com/HMFmH6m.jpg](https://i.imgur.com/HMFmH6m.jpg)',
  alt: '12 terracotta sculptures of solemn warriors, each with a unique facial expression and armor.'
}, {
  name: 'Lunar Landscape',
  artist: 'Louise Nevelson',
  description: 'Nevelson was known for scavenging objects from New York City debris, which she would later assemble into monumental constructions. In this one, she used disparate parts like a bedpost, juggling pin, and seat fragment, nailing and gluing them into boxes that reflect the influence of Cubism’s geometric abstraction of space and form.',
  url: '[https://i.imgur.com/rN7hY6om.jpg](https://i.imgur.com/rN7hY6om.jpg)',
  alt: 'A black matte sculpture where the individual elements are initially indistinguishable.'
}, {
  name: 'Aureole',
  artist: 'Ranjani Shettar',
  description: 'Shettar merges the traditional and the modern, the natural and the industrial. Her art focuses on the relationship between man and nature. Her work was described as compelling both abstractly and figuratively, gravity defying, and a "fine synthesis of unlikely materials."',
  url: '[https://i.imgur.com/okTpbHhm.jpg](https://i.imgur.com/okTpbHhm.jpg)',
  alt: 'A pale wire-like sculpture mounted on concrete wall and descending on the floor. It appears light.'
}, {
  name: 'Hippos',
  artist: 'Taipei Zoo',
  description: 'The Taipei Zoo commissioned a Hippo Square featuring submerged hippos at play.',
  url: '[https://i.imgur.com/6o5Vuyu.jpg](https://i.imgur.com/6o5Vuyu.jpg)',
  alt: 'A group of bronze hippo sculptures emerging from the sett sidewalk as if they were swimming.'
}];
button { display: block; margin-bottom: 10px; }
.Page > * {
  float: left;
  width: 50%;
  padding: 10px;
}
h2 { margin-top: 10px; margin-bottom: 0; }
h3 {
  margin-top: 5px;
  font-weight: normal;
  font-size: 100%;
}
img { width: 120px; height: 120px; }

여기서는 양쪽 이벤트 핸들러 안에 가드 조건(guard condition)을 추가하고, 필요할 때는 버튼을 비활성화시키는 방식으로 문제를 해결해 보겠습니다:

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

export default function Gallery() {
  const [index, setIndex] = useState(0);
  const [showMore, setShowMore] = useState(false);

  let hasPrev = index > 0;
  let hasNext = index < sculptureList.length - 1;

  function handlePrevClick() {
    if (hasPrev) {
      setIndex(index - 1);
    }
  }

  function handleNextClick() {
    if (hasNext) {
      setIndex(index + 1);
    }
  }

  function handleMoreClick() {
    setShowMore(!showMore);
  }

  let sculpture = sculptureList[index];
  return (
    <>
      <button
        onClick={handlePrevClick}
        disabled={!hasPrev}
      >
        Previous
      </button>
      <button
        onClick={handleNextClick}
        disabled={!hasNext}
      >
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i> 
        by {sculpture.artist}
      </h2>
      <h3>  
        ({index + 1} of {sculptureList.length})
      </h3>
      <button onClick={handleMoreClick}>
        {showMore ? 'Hide' : 'Show'} details
      </button>
      {showMore && <p>{sculpture.description}</p>}
      <img 
        src={sculpture.url} 
        alt={sculpture.alt}
      />
    </>
  );
}
// src/data.js hidden
export const sculptureList = [{
  name: 'Homenaje a la Neurocirugía',
  artist: 'Marta Colvin Andrade',
  description: 'Although Colvin is predominantly known for abstract themes that allude to pre-Hispanic symbols, this gigantic sculpture, an homage to neurosurgery, is one of her most recognizable public art pieces.',
  url: '[https://i.imgur.com/Mx7dA2Y.jpg](https://i.imgur.com/Mx7dA2Y.jpg)',
  alt: 'A bronze statue of two crossed hands delicately holding a human brain in their fingertips.'  
}, {
  name: 'Floralis Genérica',
  artist: 'Eduardo Catalano',
  description: 'This enormous (75 ft. or 23m) silver flower is located in Buenos Aires. It is designed to move, closing its petals in the evening or when strong winds blow and opening them in the morning.',
  url: '[https://i.imgur.com/ZF6s192m.jpg](https://i.imgur.com/ZF6s192m.jpg)',
  alt: 'A gigantic metallic flower sculpture with reflective mirror-like petals and strong stamens.'
}, {
  name: 'Eternal Presence',
  artist: 'John Woodrow Wilson',
  description: 'Wilson was known for his preoccupation with equality, social justice, as well as the essential and spiritual qualities of humankind. This massive (7ft. or 2,13m) bronze represents what he described as "a symbolic Black presence infused with a sense of universal humanity."',
  url: '[https://i.imgur.com/aTtVpES.jpg](https://i.imgur.com/aTtVpES.jpg)',
  alt: 'The sculpture depicting a human head seems ever-present and solemn. It radiates calm and serenity.'
}, {
  name: 'Moai',
  artist: 'Unknown Artist',
  description: 'Located on the Easter Island, there are 1,000 moai, or extant monumental statues, created by the early Rapa Nui people, which some believe represented deified ancestors.',
  url: '[https://i.imgur.com/RCwLEoQm.jpg](https://i.imgur.com/RCwLEoQm.jpg)',
  alt: 'Three monumental stone busts with the heads that are disproportionately large with somber faces.'
}, {
  name: 'Blue Nana',
  artist: 'Niki de Saint Phalle',
  description: 'The Nanas are triumphant creatures, symbols of femininity and maternity. Initially, Saint Phalle used fabric and found objects for the Nanas, and later on introduced polyester to achieve a more vibrant effect.',
  url: '[https://i.imgur.com/Sd1AgUOm.jpg](https://i.imgur.com/Sd1AgUOm.jpg)',
  alt: 'A large mosaic sculpture of a whimsical dancing female figure in a colorful costume emanating joy.'
}, {
  name: 'Ultimate Form',
  artist: 'Barbara Hepworth',
  description: 'This abstract bronze sculpture is a part of The Family of Man series located at Yorkshire Sculpture Park. Hepworth chose not to create literal representations of the world but developed abstract forms inspired by people and landscapes.',
  url: '[https://i.imgur.com/2heNQDcm.jpg](https://i.imgur.com/2heNQDcm.jpg)',
  alt: 'A tall sculpture made of three elements stacked on each other reminding of a human figure.'
}, {
  name: 'Cavaliere',
  artist: 'Lamidi Olonade Fakeye',
  description: "Descended from four generations of woodcarvers, Fakeye's work blended traditional and contemporary Yoruba themes.",
  url: '[https://i.imgur.com/wIdGuZwm.png](https://i.imgur.com/wIdGuZwm.png)',
  alt: 'An intricate wood sculpture of a warrior with a focused face on a horse adorned with patterns.'
}, {
  name: 'Big Bellies',
  artist: 'Alina Szapocznikow',
  description: "Szapocznikow is known for her sculptures of the fragmented body as a metaphor for the fragility and impermanence of youth and beauty. This sculpture depicts two very realistic large bellies stacked on top of each other, each around five feet (1,5m) tall.",
  url: '[https://i.imgur.com/AlHTAdDm.jpg](https://i.imgur.com/AlHTAdDm.jpg)',
  alt: 'The sculpture reminds a cascade of folds, quite different from bellies in classical sculptures.'
}, {
  name: 'Terracotta Army',
  artist: 'Unknown Artist',
  description: 'The Terracotta Army is a collection of terracotta sculptures depicting the armies of Qin Shi Huang, the first Emperor of China. The army consisted of more than 8,000 soldiers, 130 chariots with 520 horses, and 150 cavalry horses.',
  url: '[https://i.imgur.com/HMFmH6m.jpg](https://i.imgur.com/HMFmH6m.jpg)',
  alt: '12 terracotta sculptures of solemn warriors, each with a unique facial expression and armor.'
}, {
  name: 'Lunar Landscape',
  artist: 'Louise Nevelson',
  description: 'Nevelson was known for scavenging objects from New York City debris, which she would later assemble into monumental constructions. In this one, she used disparate parts like a bedpost, juggling pin, and seat fragment, nailing and gluing them into boxes that reflect the influence of Cubism’s geometric abstraction of space and form.',
  url: '[https://i.imgur.com/rN7hY6om.jpg](https://i.imgur.com/rN7hY6om.jpg)',
  alt: 'A black matte sculpture where the individual elements are initially indistinguishable.'
}, {
  name: 'Aureole',
  artist: 'Ranjani Shettar',
  description: 'Shettar merges the traditional and the modern, the natural and the industrial. Her art focuses on the relationship between man and nature. Her work was described as compelling both abstractly and figuratively, gravity defying, and a "fine synthesis of unlikely materials."',
  url: '[https://i.imgur.com/okTpbHhm.jpg](https://i.imgur.com/okTpbHhm.jpg)',
  alt: 'A pale wire-like sculpture mounted on concrete wall and descending on the floor. It appears light.'
}, {
  name: 'Hippos',
  artist: 'Taipei Zoo',
  description: 'The Taipei Zoo commissioned a Hippo Square featuring submerged hippos at play.',
  url: '[https://i.imgur.com/6o5Vuyu.jpg](https://i.imgur.com/6o5Vuyu.jpg)',
  alt: 'A group of bronze hippo sculptures emerging from the sett sidewalk as if they were swimming.'
}];
button { display: block; margin-bottom: 10px; }
.Page > * {
  float: left;
  width: 50%;
  padding: 10px;
}
h2 { margin-top: 10px; margin-bottom: 0; }
h3 {
  margin-top: 5px;
  font-weight: normal;
  font-size: 100%;
}
img { width: 120px; height: 120px; }

hasPrevhasNext 변수가 반환되는 JSX 안에서도 쓰이고, 동시에 이벤트 핸들러 안에서도 쓰이고 있다는 점을 잘 살펴보세요! 이 편리한 패턴은 이벤트 핸들러 함수들이 렌더링 도중에 선언된 변수들을 "클로저(close over)"하기 때문에 아주 잘 작동한답니다.

(💡 강사의 보충 설명: 자바스크립트의 클로저 특성 덕분에, 렌더링될 때의 변수 상태를 이벤트 핸들러 함수가 그대로 "기억"해서 가져다 쓸 수 있는 거예요.)

고장난 폼 입력 필드 고치기 {/fix-stuck-form-inputs/}

입력 필드에 아무리 글자를 타이핑해도 빈 문자열에 "고정"된 것처럼 아무것도 나타나지 않습니다. 첫 번째 <input>value는 항상 firstName 변수와 일치하도록 설정되어 있고, 두 번째 <input>value는 항상 lastName 변수와 일치하도록 설정되어 있습니다. 여기까지는 맞습니다. 두 입력 필드 모두 사용자의 최신 입력값(e.target.value)을 바탕으로 변수를 업데이트하려는 onChange 이벤트 핸들러를 가지고 있습니다. 하지만 이 변수들은 다시 렌더링될 때 자신의 값을 "기억"하지 못하는 것 같네요. 변수를 상태 변수로 바꾸어 이 문제를 해결해 보세요.

// {expectedErrors: {'react-compiler': [6]}}
export default function Form() {
  let firstName = '';
  let lastName = '';

  function handleFirstNameChange(e) {
    firstName = e.target.value;
  }

  function handleLastNameChange(e) {
    lastName = e.target.value;
  }

  function handleReset() {
    firstName = '';
    lastName = '';
  }

  return (
    <form onSubmit={e => e.preventDefault()}>
      <input
        placeholder="First name"
        value={firstName}
        onChange={handleFirstNameChange}
      />
      <input
        placeholder="Last name"
        value={lastName}
        onChange={handleLastNameChange}
      />
      <h1>Hi, {firstName} {lastName}</h1>
      <button onClick={handleReset}>Reset</button>
    </form>
  );
}
h1 { margin-top: 10px; }

먼저 React에서 useState를 불러옵니다. 그런 다음 firstNamelastName을 일반 변수 대신 useState를 호출하여 선언한 상태 변수로 바꿔줍니다. 마지막으로, 모든 firstName = ... 할당문을 setFirstName(...)으로 교체하고 lastName에 대해서도 똑같이 작업해 줍니다. 초기화(Reset) 버튼이 잘 작동하도록 handleReset 함수를 업데이트하는 것도 잊지 마세요!

import { useState } from 'react';

export default function Form() {
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');

  function handleFirstNameChange(e) {
    setFirstName(e.target.value);
  }

  function handleLastNameChange(e) {
    setLastName(e.target.value);
  }

  function handleReset() {
    setFirstName('');
    setLastName('');
  }

  return (
    <form onSubmit={e => e.preventDefault()}>
      <input
        placeholder="First name"
        value={firstName}
        onChange={handleFirstNameChange}
      />
      <input
        placeholder="Last name"
        value={lastName}
        onChange={handleLastNameChange}
      />
      <h1>Hi, {firstName} {lastName}</h1>
      <button onClick={handleReset}>Reset</button>
    </form>
  );
}
h1 { margin-top: 10px; }

앱 충돌(크래시) 해결하기 {/fix-a-crash/}

여기 사용자가 피드백을 남길 수 있도록 만든 작은 폼이 있습니다. 피드백이 전송되고 나면 감사의 메시지를 표시하려고 해요. 그런데 이 앱을 실행하면 "Rendered fewer hooks than expected (예상보다 적은 수의 Hook이 렌더링되었습니다)"라는 에러 메시지와 함께 충돌이 일어납니다. 코드에서 실수한 부분을 찾아 고칠 수 있을까요?

Hook을 호출할 수 있는 위치에 어떤 제한이 있었는지 기억나시나요? 이 컴포넌트가 규칙을 어긴 부분이 있을까요? 린터(linter) 검사를 비활성화하는 주석이 있는지 찾아보세요 -- 보통 버그는 그런 곳에 숨어있기 마련이니까요!

// {expectedErrors: {'react-compiler': [9]}}
import { useState } from 'react';

export default function FeedbackForm() {
  const [isSent, setIsSent] = useState(false);
  if (isSent) {
    return <h1>Thank you!</h1>;
  } else {
    // eslint-disable-next-line
    const [message, setMessage] = useState('');
    return (
      <form onSubmit={e => {
        e.preventDefault();
        alert(`Sending: "${message}"`);
        setIsSent(true);
      }}>
        <textarea
          placeholder="Message"
          value={message}
          onChange={e => setMessage(e.target.value)}
        />
        <br />
        <button type="submit">Send</button>
      </form>
    );
  }
}

Hook은 항상 컴포넌트 함수의 최상위 레벨에서만 호출되어야 합니다. 이 코드에서 첫 번째 isSent 정의는 규칙을 잘 따랐지만, 두 번째 message 정의는 조건문 내부의 분기점 안에 중첩되어 있습니다.

문제를 해결하려면 Hook 호출을 조건문 밖으로 빼내야 합니다:

import { useState } from 'react';

export default function FeedbackForm() {
  const [isSent, setIsSent] = useState(false);
  const [message, setMessage] = useState('');

  if (isSent) {
    return <h1>Thank you!</h1>;
  } else {
    return (
      <form onSubmit={e => {
        e.preventDefault();
        alert(`Sending: "${message}"`);
        setIsSent(true);
      }}>
        <textarea
          placeholder="Message"
          value={message}
          onChange={e => setMessage(e.target.value)}
        />
        <br />
        <button type="submit">Send</button>
      </form>
    );
  }
}

명심하세요, Hook은 반드시 무조건적으로 호출되어야 하며, 매 렌더링마다 항상 똑같은 순서로 호출되어야 합니다!

불필요한 else 브랜치를 제거해서 중첩 구조를 줄이는 것도 좋은 방법입니다. 물론 그렇다 하더라도, 모든 Hook에 대한 호출은 여전히 첫 번째 return이 실행되기 에 모두 일어나야만 한다는 사실은 변하지 않습니다.

import { useState } from 'react';

export default function FeedbackForm() {
  const [isSent, setIsSent] = useState(false);
  const [message, setMessage] = useState('');

  if (isSent) {
    return <h1>Thank you!</h1>;
  }

  return (
    <form onSubmit={e => {
      e.preventDefault();
      alert(`Sending: "${message}"`);
      setIsSent(true);
    }}>
      <textarea
        placeholder="Message"
        value={message}
        onChange={e => setMessage(e.target.value)}
      />
      <br />
      <button type="submit">Send</button>
    </form>
  );
}

두 번째 useState 호출을 if 조건문 뒤로 이동시켜 보고 어떻게 다시 에러가 발생하는지 직접 확인해 보세요.

여러분의 린터가 React에 맞게 잘 설정되어 있다면, 이런 종류의 실수를 했을 때 에러 메시지를 볼 수 있을 겁니다. 만약 로컬 환경에서 잘못된 코드를 입력했는데 에러가 보이지 않는다면, 프로젝트에 린트(linting) 설정을 꼭 적용하셔야 합니다.

불필요한 State 제거하기 {/remove-unnecessary-state/}

버튼을 클릭했을 때 사용자에게 이름을 묻는 창을 띄우고, 그 이름으로 인사말 경고창을 표시하려고 만든 예제입니다. 이름을 유지하기 위해 상태 변수를 도입했지만, 무슨 이유에서인지 처음에는 "Hello, !"라고 표시되고, 그 이후부터는 항상 이전에 입력했던 이름으로 "Hello, [이전 이름]!"이 표시되고 있습니다.

이 불필요한 상태 변수를 아예 제거해서 코드를 고쳐보세요. (왜 이 코드가 의도대로 작동하지 않았는지에 대해서는 나중에 스냅샷으로서의 State (State as a Snapshot) 장에서 깊이 다룰 예정입니다.)

왜 이 상태 변수가 굳이 필요 없었는지 설명하실 수 있나요?

import { useState } from 'react';

export default function FeedbackForm() {
  const [name, setName] = useState('');

  function handleClick() {
    setName(prompt('What is your name?'));
    alert(`Hello, ${name}!`);
  }

  return (
    <button onClick={handleClick}>
      Greet
    </button>
  );
}

필요한 변수를 그 함수 내부에서 일반 name 변수로 선언하여 문제를 해결한 버전은 다음과 같습니다:

export default function FeedbackForm() {
  function handleClick() {
    const name = prompt('What is your name?');
    alert(`Hello, ${name}!`);
  }

  return (
    <button onClick={handleClick}>
      Greet
    </button>
  );
}

상태 변수는 컴포넌트가 다시 렌더링되는 과정 사이에 정보를 유지해야 할 때만 필요합니다. 단일 이벤트 핸들러 안에서 값을 바로 받아서 바로 사용할 목적이라면, 일반 지역 변수로도 아주 충분합니다. 일반 변수로도 잘 작동하는 곳에 굳이 무거운 상태 변수를 끌어들이지 마세요.

(💡 강사의 보충 설명: handleClick 이라는 한 번의 실행 흐름 안에서 입력받고 바로 경고창 띄우는 것으로 끝나기 때문에 화면을 '새로 고침(리렌더링)'할 필요 자체가 없었던 거랍니다!)


사이트맵 (Sitemap)

모든 공식문서 페이지 한눈에 보기 (Overview of all docs pages)

profile
프론트에_가까운_풀스택_개발자

0개의 댓글