HancomAI_academy/React

9. State와 useState

k1212gh 2025. 3. 3. 00:18

[스나이퍼팩토리] 한컴AI - AI개발자 교육 React.js 9차시: State와 useState


📌 학습 목표

✅ React에서 State의 개념과 역할을 이해한다.
✅ useState 훅을 활용하여 상태를 관리하는 방법을 익힌다.
✅ State의 비동기적 특성과 올바른 업데이트 방법을 학습한다.
State와 Props의 차이점을 이해하고, 적절한 상황에서 활용하는 방법을 배운다.


📚 학습 내용

1. State란?

  • State컴포넌트 내부에서 관리되는 동적인 데이터로, 시간이 지남에 따라 변경될 수 있다.
  • State가 변경되면 해당 컴포넌트가 다시 렌더링되어 UI가 업데이트된다.
  • Props와 달리 State는 컴포넌트 내부에서 직접 관리하고 변경할 수 있다.

🔹 Props vs State 차이점

    Props      vs     State               

부모에서 자식으로 전달됨 컴포넌트 내부에서 관리됨
읽기 전용 (변경 불가) 변경 가능 (업데이트 시 렌더링됨)
부모가 변경해야 반영됨 내부에서 직접 변경 가능
컴포넌트 간 데이터 전달 용도 UI 상태 관리 용도

 


2. useState 훅 사용법

🔹 기본적인 State 사용

import React, { useState } from "react";

function Counter() {
  // State 정의
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}
  • useState(초기값)을 호출하면 배열을 반환하며,
    • 첫 번째 요소는 현재 상태 값
    • 두 번째 요소는 상태를 변경하는 함수 (setCount)
  • setCount(newValue)를 호출하면 React가 해당 값을 업데이트하고 컴포넌트를 다시 렌더링한다.

3. 다양한 State 사용 예시

🔹 문자열 State 관리

function NameInput() {
  const [name, setName] = useState("");

  return (
    <div>
      <input
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
      <p>Your name is: {name}</p>
    </div>
  );
}
  • 입력 필드의 값을 State로 관리하여 실시간 업데이트가 가능하다.

🔹 객체 State 관리

function UserProfile() {
  const [user, setUser] = useState({ name: "", age: 0 });

  const updateName = (newName) => {
    setUser((prevUser) => ({ ...prevUser, name: newName }));
  };

  return (
    <div>
      <input value={user.name} onChange={(e) => updateName(e.target.value)} />
      <p>Name: {user.name}</p>
    </div>
  );
}
  • 객체를 State로 관리할 때 setState를 직접 호출하는 것이 아니라, 기존 객체를 복사(...prevUser)한 후 변경해야 한다.
  • React에서 State는 불변성을 유지해야 하므로, 직접 수정하지 않고 새로운 객체를 생성하는 것이 중요하다.

🔹 배열 State 관리

function TodoList() {
  const [todos, setTodos] = useState([]);

  const addTodo = () => {
    setTodos([...todos, `New Task ${todos.length + 1}`]);
  };

  return (
    <div>
      <button onClick={addTodo}>Add Task</button>
      <ul>
        {todos.map((todo, index) => (
          <li key={index}>{todo}</li>
        ))}
      </ul>
    </div>
  );
}
  • 배열을 직접 수정하는 것이 아니라, 기존 배열을 복사한 후 새로운 요소를 추가해야 한다.

4. State 업데이트 시 주의해야 할 점

🔹 State 업데이트는 비동기적이다.

function Counter() {
  const [count, setCount] = useState(0);

  const increment = () => {
    setCount(count + 1);
    setCount(count + 1); // 예상과 다르게 한 번만 증가됨
  };

  return <button onClick={increment}>Increment</button>;
}
  • setState는 비동기적으로 작동하므로, 여러 번 호출해도 동일한 값을 사용할 수 있다.

🔹 이전 State를 기반으로 업데이트하기

function Counter() {
  const [count, setCount] = useState(0);

  const increment = () => {
    setCount((prevCount) => prevCount + 1);
    setCount((prevCount) => prevCount + 1); // 두 번 증가
  };

  return <button onClick={increment}>Increment</button>;
}
  • 이전 값을 기반으로 업데이트할 때는 setState에 함수형 업데이트를 사용해야 한다.

💡 추가로 알면 좋은 사항

🔹 State 초기값을 함수로 설정하기

function getInitialCount() {
  console.log("Initializing count...");
  return 0;
}

const [count, setCount] = useState(getInitialCount);
  • useState(초기값)에 직접 값을 전달하면 매 렌더링마다 실행되지만,
    useState(() => 초기값)을 사용하면 처음 한 번만 실행된다.

🔹 useEffect와 함께 사용하기

import { useEffect, useState } from "react";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(`Count changed: ${count}`);
  }, [count]);

  return <button onClick={() => setCount(count + 1)}>Increment</button>;
}
  • useEffect와 함께 사용하면 State 변경 시 특정 동작을 실행할 수 있다.

🔎 학습 회고

✅ React에서 State는 동적인 데이터를 관리하는 핵심 요소라는 점을 알게 되었다.
✅ useState를 사용하면 다양한 형태의 데이터(문자열, 객체, 배열 등)를 관리할 수 있다.
State 업데이트가 비동기적으로 동작한다는 점을 주의해야 한다.
✅ 앞으로 useEffect, Context API를 활용하여 더욱 효율적인 상태 관리를 해보고 싶다.


🛠 실습 예제

function App() {
  return (
    <div>
      <Counter />
      <NameInput />
      <TodoList />
    </div>
  );
}

export default App;
  • 다양한 State 예제를 조합하여 실습하며, React의 동적 UI 구현을 익힐 수 있다.

 

🔎 다음 목표

 
State와 Props의 차이를 명확하게 이해하고, 동적인 데이터를 다룰 수 있습니다! 다음 학습에서는 조건부 렌더링과 이벤트 핸들링을 활용하여 더 복잡한 UI를 구현