49일차[useState]

진하의 메모장·2025년 3월 19일
1

공부일기

목록 보기
54/66
post-thumbnail

2025 / 03 / 18

오늘 수업 시간에는 리액트 훅과 useState에 대해 배웠습니다.
useState를 사용해 내용을 동적으로 바꾸는 실습을 했는데, 초반에 독학으로 리액트를 공부했다가.. 포기했던 기억이..ㅠㅜ 하지만 다시 열심히 공부해보겠습니다.



💌 useState

  • React의 훅 중 하나로, 컴토넌트의 상태를 관리하는 데 사용됩니다.
  • 컴포넌트 내에서 상태를 저장하고, 변경될 때마다 UI를 업데이트할 수 있습니다.
const [state, setState] = useState(Value);

state

  • 컴포넌트에서 관리하고자 하는 상태 값입니다.

setState

  • 상태를 변경할 수 있는 함수입니다.
  • 이 함수를 사용하여 state의 값을 변경할 수 있습니다.

Value

  • 상태의 초기값입니다.
  • useState는 첫 번째 렌더링에서 이 값을 사용하여 상태를 초기화합니다.


1. 간단한 예시

숫자 카운터 프로그램

import React, { useState } from "react";

function Counter() {
  // 초기값 0으로 설정된 상태를 관리
  const [count, setCount] = useState(0);

  // 버튼 클릭 시 상태를 증가시키는 함수
  return (
    <div>
      <h2>카운트: {count}</h2>
      <button onClick={() => setCount(count + 1)}>카운트 증가</button>
      <button onClick={() => setCount(count - 1)}>카운트 감소</button>
    </div>
  );
}

export default Counter;

useState(0)

  • count라는 상태를 관리합니다.
  • 0은 상태의 초기값입니다.

setCount(count + 1), setCount(count - 1)

  • count 값을 1씩 증가시키거나 감소시키는 함수입니다.

  • 버튼을 클릭할 때마다 상태가 업데이트되고, React는 자동으로 UI를 리렌더링합니다.


2. 특징

1. 상태 값 저장

  • 컴포넌트의 상태 값은 useState 훅을 통해 저장됩니다.
  • 상태 값이 변경되면, React는 해당 컴포넌트를 다시 렌더링하여 UI를 업데이트 합니다.

2. 상태 변경

  • setState를 사용하여 상태를 변경합니다.
  • 이 때 상태는 비동기적으로 업데이트합니다.
  • 상태가 업데이트되었을 때, 바로 UI에 반영되지 않고 렌더링 후 반영됩니다.

3. 컴포넌트 간 상태 전달

  • useState는 상태를 컴포넌트 내부에서만 관리합니다.
  • 상태를 다른 컴포넌트로 전달하고 싶다면, props를 사용하거나 상위 컴포넌트로 상태를 끌어올리는 방법(lifting state up)을 사용해야합니다.


3. 동작 방식

  • useState의 중요한 특징은 상태가 변경될 때 컴포넌트가 다시 렌더링된다는 점입니다.
import React, { useState } from "react";

function Example() {
  const [value, setValue] = useState(0);

  console.log(value);  // 상태가 변경되기 전, 즉 렌더링 시마다 출력됨

  return (
    <div>
      <h1>{value}</h1>
      <button onClick={() => setValue(value + 1)}>Increment</button>
    </div>
  );
}

export default Example;
  • setValue는 value 상태를 변경하는 함수입니다.
  • 상태를 변경하려면 컴포넌트가 다시 렌더링됩니다.
  • 상태 변경 후 UI에 반영된 value 값이 화면에 표시됩니다.
  • console.log(value)는 상태가 변경되기 전의 값을 출력합니다.
  • React가 상태 업데이트 후 바로 렌더링되지 않고, 렌더링 사이클이 끝난 후 반영되기 때문입니다.


4. 배열 사용하기

  • useState는 기본적으로 원시 타입(숫자, 문자열 등)을 상태로 관리하지만, 주의해야 할 점이 있지만 배열이나 객체와 같은 복잡한 자료형도 관리할 수 있습니다.
import React, { useState } from "react";

function TodoApp() {
  const [todos, setTodos] = useState(["할 일 1", "할 일 2"]);

  const addTodo = () => {
    setTodos([...todos, "새 할 일"]); // 배열 업데이트
  };

  return (
    <div>
      <ul>
        {todos.map((todo, index) => (
          <li key={index}>{todo}</li>
        ))}
      </ul>
      <button onClick={addTodo}>할 일 추가</button>
    </div>
  );
}

export default TodoApp;
  • useState로 todos라는 배열을 관리하고 있습니다.
  • 추가할 때는 기존 배열을 변경하지 않고 새 배열을 만들어서 업데이트 해야합니다.
  • ...todos(스프레트 오퍼레이터)로 기본 배열을 펼친 후, 새로운 값을 추가합니다.
  • 상태가 업데이트되면 컴포넌트가 다시 렌더링되어, 추가된 할 일이 화면에 표시됩니다.


5. 객체 사용하기

  • useState를 사용하여 객체의 형태로도 상태를 관리할 수 있습니다.
import React, { useState } from "react";

function Profile() {
  const [profile, setProfile] = useState({ name: "진하", age: 23 });

  const updateProfile = () => {
    setProfile({ ...profile, age: profile.age + 1 }); // 객체 업데이트
  };

  return (
    <div>
      <h1>{profile.name}</h1>
      <p>나이: {profile.age}</p>
      <button onClick={updateProfile}>나이 증가</button>
    </div>
  );
}

export default Profile;
  • useState로 profile이라는 객체를 관리하고 있습니다.
  • 객체 상태를 업데이트할 때는 기존 객체를 변경하지 않고, 객체를 펼친 후 새로운 값을 덮어씌워서 상태를 업데이트해야 합니다.
  • setProfile({ ...profile, age: profile.age + 1 })와 같이 사용합니다.


💌 실습 문제 분석

  • 수업 시간에 작성한 실습 문제를 분석하며 useState를 알아보겠습니다.

1. App 컴포넌트

App 컴포넌트 분석

import { useState } from "react";
import reactImg from "./assets/react.png";
import reactImg2 from "./assets/cat.png";
import reactImg3 from "./assets/dog.png";

import Card from "./components/Card";
import TabButton from "./components/TabButton";

function App() {
  // useState를 사용하여 상태를 정의
  const [label, setLabel] = useState("");

  // 탭을 클릭했을 때 실행되는 함수
  function tabclick(selectedLabel) {
    console.log(`${selectedLabel} 선택됨`);
    setLabel(selectedLabel); // 상태 업데이트
  }

  return (
    <div className="app">
      <h1>React Props 연습</h1>
      <div className="card-container">
        <Card
          title="React Props"
          content="React Props는 컴포넌트에 데이터를 전달하는 방법입니다."
          img={reactImg}
          backgroundColor="#ffe3e3"
          color="#6e1919"
        />
        <Card
          title="Cat"
          content="고양이는 귀엽다."
          img={reactImg2}
          backgroundColor="#feffe0"
          color="#4e5716"
        />
        <Card
          title="Dog"
          content="강아지는 더 귀엽다."
          img={reactImg3}
          backgroundColor="#e0f1ff"
          color="#18588c"
        />
      </div>
      <section className="example">
        <h2>예시</h2>
        <menu>
          <TabButton label="data" on={tabclick}>데이터 전달</TabButton>
          <TabButton label="component" on={tabclick}>재사용 컴포넌트</TabButton>
          <TabButton label="style" on={tabclick}>동적 스타일링</TabButton>
        </menu>
        <br />
        <hr />
        <br />
        <h3>{label}</h3> {/* 선택된 label이 표시됨 */}
      </section>
    </div>
  );
}

export default App;

1. useState 훅 사용하기

useState 사용

const [label, setLabel] = useState("");
  • useState는 React에서 상태를 관리하는 핵심적인 도구입니다.
  • 여기서 label은 컴포넌트의 상태이며, 처음에는 빈 문자열 ""로 초기화됩니다.
  • label 상태는 이후 탭 버튼을 클릭할 때마다 변경됩니다.
  • setLabel은 상태를 변경할 수 있는 함수입니다.
  • 이 함수는 label의 값을 업데이트하고, 컴포넌트가 다시 렌더링됩니다.


2. tabclick 함수

tabclick 함수 생성

function tabclick(selectedLabel) {
  console.log(`${selectedLabel} 선택됨`);
  setLabel(selectedLabel); // 상태 업데이트
}
  • tabclick 함수는 각 탭 버튼을 클릭했을 때 실행됩니다.
  • 버튼을 클릭하면 selectedLabel 값을 받아옵니다.
  • 받아온 값을 setLabel에 전달하여 label 상태를 업데이트합니다.
  • setLabel(selectedLabel)로 상태가 업데이트됩니다.
  • 그 후 React는 컴포넌트를 재렌더링하여 화면에 변경된 label 값이 표시됩니다.
  • 상태 업데이트가 비동기적으로 일어난다는 점이 중요합니다.
  • label 값은 즉시 업데이트되는 것이 아니라, React의 렌더링 사이클을 거쳐 화면에 반영됩니다.


3. Card 컴포넌트

Card 컴포넌트 사용

<Card
  title="React Props"
  content="React Props는 컴포넌트에 데이터를 전달하는 방법입니다."
  img={reactImg}
  backgroundColor="#ffe3e3"
  color="#6e1919"
/>
<Card
  title="Cat"
  content="고양이는 귀엽다."
  img={reactImg2}
  backgroundColor="#feffe0"
  color="#4e5716"
/>
<Card
  title="Dog"
  content="강아지는 더 귀엽다."
  img={reactImg3}
  backgroundColor="#e0f1ff"
  color="#18588c"
/>

title

  • 각 카드의 제목을 설정합니다.

content

  • 카드의 본문 내용입니다.

img

  • 각 카드에 보여줄 이미지를 설정합니다.

backgroundColor, color

  • Card의 스타일을 설정하는 값입니다.
  • 각 카드마다 다른 배경색과 텍스트 색을 적용할 수 있습니다.


4. TabButton 컴포넌트

TabButton 컴포넌트 사용

<TabButton label="data" on={tabclick}>데이터 전달</TabButton>
<TabButton label="component" on={tabclick}>재사용 컴포넌트</TabButton>
<TabButton label="style" on={tabclick}>동적 스타일링</TabButton>
  • 각 TabButton 컴포넌트는 label과 on이라는 두 가지 props를 전달받습니다.

label

  • 각 탭 버튼의 고유 값입니다.
  • 예를 들어, 첫 번째 버튼은 "data", 두 번째 버튼은 "component" 값을 전달받습니다.

on

  • tabclick 함수를 전달받아 클릭할 때 해당 함수를 실행하도록 합니다.

  • TabButton 컴포넌트는 재사용 가능한 컴포넌트입니다.

  • 클릭된 탭에 따라 label 값을 업데이트하는 역할을 합니다.



2. Card 컴포넌트 내부

Card.jsx

export default function Card({ title, content, img, ...divStyle }) {
  return (
    <div className={styles.card} style={divStyle}>
      <img src={img} alt="" />
      <h2 className={styles["card-title"]}>{title}</h2>
      <p className={styles["card-content"]}>{content}</p>
    </div>
  );
}

1. props로 받는 값들

Card({ title, content, img, ...divStyle })

title, content, img

  • Card 내부에서 각각 카드의 제목, 내용, 이미지를 렌더링하는 데 사용됩니다.

...divStyle

  • 나머지 스타일 속성들(예: backgroundColor, color)을 받아서 카드의 스타일에 적용합니다.


2. 렌더링

  • div의 style={divStyle}로 스타일이 동적으로 적용됩니다.
  • title, content, img는 각 카드의 텍스트와 이미지를 설정합니다.


3. 중요한 점

  • ...divStyle : 나머지 스타일 속성을 받아서 div의 style로 적용.
  • 부모 컴포넌트에서 각 카드에 다른 스타일, 내용을 전달하여 UI를 만들 수 있습니다.


3. TabButton 컴포넌트 내부

TabButton.jsx

function TabButton({ label, on, children }) {
  return (
    <li>
      <button
        onClick={() => {
          on(label); // 클릭 시 on 함수에 label 값을 전달
        }}

        {children} {/* 버튼 내부에 표시될 텍스트 */}
      </button>
    </li>
  );
}
  • onClick 이벤트가 발생하면, 전달받은 on 함수 (여기서는 tabclick)가 호출됩니다.
  • on(label)로 현재 버튼에 해당하는 label 값을 전달합니다.
  • 이를 통해 App 컴포넌트의 tabclick 함수가 실행됩니다.
  • tabclick 함수가 실행될 때, 해당 탭 버튼의 label 값이 상태로 설정됩니다.
  • children은 버튼 내부의 내용을 나타냅니다.
  • 예를 들어 "데이터 전달", "재사용 컴포넌트", "동적 스타일링" 등이 버튼에 표시됩니다.


1. label 상태 변경 및 화면 업데이트

상태 변경 및 업데이트

<h3>{label}</h3> {/* 선택된 label이 화면에 표시됨 */}
  • 이 부분은 label 상태가 변경될 때마다 해당 값이 화면에 자동으로 렌더링되는 부분입니다.
  • 사용자가 탭 버튼을 클릭하면 label이 업데이트됩니다.
  • 그 후 <h3>{label}</h3>가 다시 렌더링되어 화면에 선택된 탭의 내용이 표시됩니다.


4. 전체 흐름

1. 초기 상태

  • label은 빈 문자열로 초기화됩니다.

2. 탭 클릭

  • 사용자가 탭 버튼을 클릭하면 tabclick 함수가 실행됩니다.
  • 해당 버튼의 label 값이 setLabel을 통해 상태로 설정됩니다.

3. 상태 변경

  • setLabel이 호출되면 React는 컴포넌트를 재렌더링합니다.
  • label의 새로운 값이 화면에 표시됩니다.

4. 결과

  • <h3>{label}</h3>가 렌더링됩니다.
  • 사용자가 클릭한 탭에 해당하는 label 값이 화면에 나타납니다.



49일차 후기

  • 혼자서 공부할 때는 막막했던 부분이 수업을 들으면서 하니까 헷갈리는 부분도 적고 찾아봐야할 부분도 줄어서 나름 힘들지 않게 핵심을 알 수 있었습니다.
  • 파일을 이동하면서 작업을 하다보니 중간에 헷갈리는 부분이 있는 것 같습니다.
  • useState 사용 방법은 완벽히는 아니지만, 헷갈리지 않을 정도로는 이해한 것 같습니다.
  • React 훅에서 가장 기본적이고 많이 사용하는 부분이기 때문에 복습은 당연한 것 같고, 앞으로 자주 사용하면서 감을 익혀나가야할 것 같습니다. 화이팅..ヾ(๑╹◡╹)ノ"
profile
૮꒰ ྀི〃´꒳`〃꒱ა

0개의 댓글