[React] useState

윤지·2024년 11월 30일

React

목록 보기
13/15
post-thumbnail

1. 리액트에서 변수 선언 방식

1. 일반 변수 선언 (화면 렌더링에 영향 없음)

  • let, const, var로 선언된 변수들은 리액트가 변화 추적 불가

2. 상태 변수 선언 (화면 렌더링에 영향 있음)

  • useState와 같은 리액트 훅으로 선언
  • 상태 변경 시 화면 자동 리렌더링

2. useState: 제어 컨트롤러 상태 관리

React에서 상태를 사용해 폼 요소나 화면 UI를 제어 컨트롤러 방식으로 관리 가능

제어 컨트롤러란?

  • 제어 컨트롤러는 React 상태를 사용해 폼 요소나 UI를 실시간으로 제어하는 방식임

useState란?

  • React 16.8에 도입된 훅(hook)
  • 상태와 상태를 변경하는 함수를 배열로 반환

기본 문법

// 비구조화할당
const [state, setState] = useState(초기값);
  • state: 현재 상태 값
  • setState: 상태 값을 변경하는 함수
  • 초기값: 상태의 초기값

3. useState 사용 예제

상태 관리로 화면 렌더링 반영

import { useState } from "react";

export default function App() {
  const [count, setCount] = useState(0);

  const increment = () => {
    setCount(count + 1); //값 전달 시 count의 최신값으로 설정
  };

  return (
    <div>
      <h1>count: {count}</h1>
      <button onClick={increment}>증가</button>
    </div>
  );
}

✅ 관례

  • 상태 이름이 count면 업데이트 함수는 setCount로 작명
  • 예: isVisiblesetIsVisible, userNamesetUserName

4. setState의 두 가지 사용 방식

1. 값 전달 방식

setCount(count + 1); //값 전달 시 count의 최신값으로 설정
  • 이전 상태를 참조하지 않을 때 사용

2. 콜백 함수 방식 setState((현재상태) ⇒ 값)

setCount((count) => count + 1); //콜백함수 반환값이 count의 최신값으로 설정
  • 이전 상태를 참조해야 할 때 사용

3. 두 방식 차이점

값 전달 방식과 콜백 함수 방식의 주요 차이점은 상태 업데이트의 동작 방식에 있음

예시: 3번의 상태 업데이트 시도

const increment = () => {
  setCount(count + 1);
  setCount(count + 1);
  setCount(count + 1);
};

count는 1만 증가함. 각 setCount가 동일한 count 값을 참조하기 때문(비동기)

하지만 콜백 함수 사용 시:

const increment = () => {
  setCount(prev => prev + 1);
  setCount(prev => prev + 1);
  setCount(prev => prev + 1);
};

count가 3씩 증가함. 각 콜백이 이전 상태의 최신값을 참조하여 업데이트하기 때문


5. 리액트에서의 불변성

React는 불변성을 기반으로 상태 변화를 감지

✅ 즉, 상태를 직접 변경하지 않고 새로운 상태를 생성해야 함

배열 상태 예제

const [students, setStudents] = useState(["james", "john"]);

const addStudent = () => {
  // ❌ 잘못된 방식 (원본 수정)
  // students.push("smith");
  // setStudents(students);

  // ✅ 올바른 방식 (새 배열 생성)
  setStudents((prevStudents) => [...prevStudents, "smith"]);
};

💡 올바른 방식: spread 연산자(...), map(), filter()를 사용해 새로운 상태를 생성


6. 제네릭 타입으로 상태 관리

타입스크립트와 useState

interface User {
  name: string;
  age: number;
  gender?: string; // 선택적(optional) 속성
}

const [user, setUser] = useState<User>({ name: "john", age: 20 });

// gender는 선택적 속성으로 추가 가능
const updateUser = () => {
  setUser(prev => ({ ...prev, gender: "male" }));
};

7. 폼 요소 상태 관리

input[type="text"]

const [input, setInput] = useState("");

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  setInput(e.target.value);
};

return <input type="text" value={input} onChange={handleChange} />;

// 혹은 onChange 내에서 직접 호출
<input type="text" value={input} onChange={(e) => setInput(e.target.value)} />

💡 valueonChange는 폼 요소 제어 시 세트로 사용

  • value 속성 없으면 리셋 기능 추가해도 인풋 내부 값 제어 불가
  • 폼 요소 완전 제어를 위해 value와 onChange 함께 사용 필수

input[type='date']

// date input
const [dateInput, setDateInput] = useState("");
<input type="date" value={dateInput} onChange={(e) => setDateInput(e.target.value)} />

textarea

// textarea
const [textInput, setTextInput] = useState("초기값");
<textarea value={textInput} onChange={(e) => setTextInput(e.target.value)} />

체크박스

const [checked, setChecked] = useState(false);
<input type="checkbox" checked={checked} onChange={() => setChecked(!checked)} />;

radio

초기값 설정 필수 ⇒ defaultChecked 설정

const [radioValue, setRadioValue] = useState("male");
      <div>
        <input
          type="radio"
          name="gender"
          className="border border-slate-500"
          value={"male"}
          defaultChecked
          onChange={() => setRadioValue("male")}
        />
        male
      </div>
      <div>
        <input
          type="radio"
          name="gender"
          className="border border-slate-500"
          value={"female"}
          onChange={() => setRadioValue("female")}
        />
        female
      </div>

셀렉트 박스

select 요소 초기값 지정 시 defaultValue 속성 사용 가능

value와 defaultValue 차이점

  • value: 컴포넌트가 제어되는 상태로, React에 의해 값이 관리됨
  • defaultValue: 컴포넌트의 초기값만 설정하고 이후 React의 제어를 받지 않음
const [selected, setSelected] = useState("apple");
<select value={selected} onChange={(e) => setSelected(e.target.value)}>
  <option value="apple">Apple</option>
  <option value="banana">Banana</option>
</select>;

출처: 수코딩

profile
프론트엔드 공부 기록 아카이빙🍁

4개의 댓글

comment-user-thumbnail
2024년 11월 30일

진짜 깔끔하네요

1개의 답글