🔷 React

[React] State로 사용자 입력 관리하기

코딩하세현 2025. 4. 9. 01:20
728x90

회원가입 폼 렌더링해보기

더보기

import { useState } from 'react';

  • useState는 React의 상태 관리를 위한 Hook인데,
  • App.js 파일 안이나 Register 컴포넌트 안에서 사용되지 않았음.
  • 사용하지 않는 import는 보통 경고가 뜨거나 불필요한 코드가 되니까 삭제해도 무방

그럼 언제 사용하냐?

seState는 "상태를 저장하고 바꾸고 싶을 때" 사용해!

예를 들어 버튼을 클릭하면 숫자가 올라가는 기능을 만들때

상황 useState 써야 할까?
버튼 누르면 값이 바뀌어야 해 o
입력창에 글 쓰면 실시간으로 상태 저장 o
어떤 요소를 숨기거나 보여주고 싶을 때 o
단순히 텍스트/컴포넌트 보여주기만 할 때 x
import { useState } from 'react';
// 간단한 회원가입 폼
// 1. 이름
// 2. 생년월일
// 3. 국적
// 4. 자기소개

const Register = () => {
  // 초- 초기 값 설정하고 싶으면 useState('여기에 적기');
  const [name, setName] = useState('이름');
  const [birth, setBirth] = useState('');
  const [country, setCountry] = useState('');
  const [bio, setBio] = useState('');

  const onChangeName = (e) => {
    // console.log(e);
    // e.target.value; // value 프로퍼티에 접근하면 현재 사용자가 작성한 텍스트에 접근 가능
    setName(e.target.value);
  };

  const onChangeBirth = (e) => {
    setBirth(e.target.value);
  };

  const onChangeCountry = (e) => {
    setCountry(e.target.value);
  };

  const onChangeBio = (e) => {
    setBio(e.target.value);
  };
  return (
    <div>
      {/* div로 감싸면 한 줄씩 보여준다. */}
      <div>
        {/* 초 - input태그의 value 속성으로 이 state인 name 설정하기 */}
        <input value={name} onChange={onChangeName} placeholder={'이름'} />
        {/* 입력 값 보여줌 */}
        {/* {name} */}
      </div>

      <div>
        {/* date picker 렌더링 */}
        <input value={birth} onChange={onChangeBirth} type="date" />
      </div>

      <div>
        {/* select는 기본으로 맨 위에 있는 옵션이 됨, 만일 아무것도 안하고 싶으면 빈 옵션 넣기 */}
        <select value={country} onChange={onChangeCountry}>
          <option></option>
          {/* value로 더 간결한 값을 사용하는 경우가 많다.  */}
          <option value="kr">한국</option>
          <option>미국</option>
          <option>일본</option>
        </select>
      </div>

      <div>
        <textarea value={bio} onChange={onChangeBio} />
      </div>
    </div>
  );
};

export default Register;

onChange 속성말고도 value 속성도 함께 적용해주기 

State로 사용자 입력 관리하기

✅ 4개의 state를 하나의 객체로 묶기

import { useState } from 'react';
// 간단한 회원가입 폼
// 1. 이름
// 2. 생년월일
// 3. 국적
// 4. 자기소개

const Register = () => {
  // 상태 초기화 -> 하나의 객체로 만듦
  const [input, setInput] = useState({
    name: '',
    birth: '',
    country: '',
    bio: '',
  });

  // input의 값 어떻게 변경되는지 확인 가능
  console.log(input);

  const onChangeName = (e) => {
    setInput({ ...input, name: e.target.value });
  };

  const onChangeBirth = (e) => {
    setInput({ ...input, birth: e.target.value });
  };

  const onChangeCountry = (e) => {
    setInput({ ...input, country: e.target.value });
  };

  const onChangeBio = (e) => {
    setInput({ ...input, bio: e.target.value });
  };

  return (
    <div>
      {/* div로 감싸면 한 줄씩 보여준다. */}
      <div>
        <input
          value={input.name}
          onChange={onChangeName}
          placeholder={'이름'}
        />
      </div>

      <div>
        {/* date picker 렌더링 */}
        <input value={input.birth} onChange={onChangeBirth} type="date" />
      </div>

      <div>
        {/* select는 기본으로 맨 위에 있는 옵션이 됨, 만일 아무것도 안하고 싶으면 빈 옵션 넣기 */}
        <select value={input.country} onChange={onChangeCountry}>
          <option></option>
          {/* value로 더 간결한 값을 사용하는 경우가 많다.  */}
          <option value="kr">한국</option>
          <option value="us">미국</option>
          <option value="jp">일본</option>
        </select>
      </div>

      <div>
        <textarea value={input.bio} onChange={onChangeBio} />
      </div>
    </div>
  );
};

export default Register;

여러개의 state로 나눠서 관리하든 4가지의 데이터를 객체 형태로 만들어 하나의 state로 만들었다. 

이벤트 핸들러도 하나로 묶기

import { useState } from 'react';
// 간단한 회원가입 폼
// 1. 이름
// 2. 생년월일
// 3. 국적
// 4. 자기소개

const Register = () => {
  // 상태 초기화 -> 하나의 객체로 만듦
  const [input, setInput] = useState({
    name: '',
    birth: '',
    country: '',
    bio: '',
  });

  // input의 값 어떻게 변경되는지 확인 가능
  console.log(input);

  const onChange = (e) => {
    setInput({
      ...InputDeviceInfo,
      [e.target.name]: e.target.value,
    });
  };

  return (
    <div>
      {/* div로 감싸면 한 줄씩 보여준다. */}
      <div>
        <input
          name="name"
          value={input.name}
          onChange={onChange}
          placeholder={'이름'}
        />
      </div>

      <div>
        <input
          name="birth"
          value={input.birth}
          onChange={onChange}
          type="date"
        />
      </div>

      <div>
        {/* select는 기본으로 맨 위에 있는 옵션이 됨, 만일 아무것도 안하고 싶으면 빈 옵션 넣기 */}
        <select name="country" value={input.country} onChange={onChange}>
          <option></option>
          {/* value로 더 간결한 값을 사용하는 경우가 많다.  */}
          <option value="kr">한국</option>
          <option value="us">미국</option>
          <option value="jp">일본</option>
        </select>
      </div>

      <div>
        <textarea name="bio" value={input.bio} onChange={onChange} />
      </div>
    </div>
  );
};

export default Register;

 

🔎 코드 동작 방법 살펴보기

 

1. input, select, textarea에 onChange를 모두 같은 함수로 설정했기 때문에 → 어디에 입력을 하든지 공통 onChange 함수가 실행

<input name="name" onChange={onChange} />
<input name="birth" onChange={onChange} />
<select name="country" onChange={onChange} />
<textarea name="bio" onChange={onChange} />

 

2. 그럼 onChange(e)가 실행될 때

const onChange = (e) => {
  setInput({
    ...input,
    [e.target.name]: e.target.value,
  });
};

setInput()이 실행된다

그리고 이 안에 있는 객체는 스프레드 문법(...input)으로 기존 상태를 복사한 후

[e.target.name]이라는 프로퍼티 키 e.target.value 값을 넣는다

 

 

3.  [e.target.name] 부분 (핵심)

 

자바스크립트에서 객체의 키 자리에 [ ] 대괄호를 쓰면 그 안에 있는 값이 키가 된다

예) e.target.name이 "birth"라면 → 결국 birth: e.target.value가 된다!

 

 

4. 예시 흐름 하나 따라가 봄

<input name="birth" onChange={onChange} />

사용자가 생년월일을 입력했을 때   그 입력창은 name="birth"로 되어 있음

그래서 e.target.name은 "birth" → 입력한 값은 e.target.value, 예: "2000-01-01"

 

그러면 setInput은 이렇게 실행됨:

setInput({
  ...input,
  birth: '2000-01-01'
});

6. 이렇게 하면 결과적으로

입력 필드의 name 속성에 따라 해당 필드 이름을 키로 쓰고 입력한 값을 그 키에 맞춰서 바꾸는 코드가 되는 것!

 

즉, 모든 필드에 대해서 onChange 하나로 처리 가능!

 

📝 setInput은 input 상태를 갱신하는 함수고, e.target.name을 객체의 키로 쓰고,
e.target.value를 그 키의 값으로 지정해서 전체 input 상태를 하나의 객체로 관리하는 패턴
이 패턴을 쓰면 여러 입력 필드를 하나의 핸들러로 통합해서 깔끔하게 처리할 수 있다. 

728x90