[React] 11. State로 사용자 입력 관리 (2)

서회정's avatar
Feb 25, 2026
[React] 11. State로 사용자 입력 관리 (2)

 

✅ 중복 코드 리팩토링

 
앞서 만들었던 사용자 입력을 관리하던 코드에는
중복된 코드가 많다.
 
이런 경우에는 코드를 보다 간결하게 작성해서 관리할 수 있다.
 
먼저 기존 코드를 살펴보자.
 
import { useState } from "react"; const Register = () => { const [name, setName] = useState(""); const [birth, setBirth] = useState(""); const [country, setCountry] = useState(""); const [bio, setBio] = useState(""); const onChangeName = (e) => { 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> <input value={name} onChange={onChangeName} placeholder="이름" /> </div> <div> <input value={birth} onChange={onChangeBirth} type="date" /> </div> <div> <select value={country} onChange={onChangeCountry}> <option></option> <option value="kr">한국</option> <option value="us">미국</option> <option value="uk">영국</option> </select> {country} </div> <div> <textarea value={bio} onChange={onChangeBio} /> </div> </div> ); }; export default Register;
 

1. 공통 state 묶기

 
먼저, 각각 따로 상태를 관리하던 state를
하나의 객체로 묶어 관리할 수 있도록
기존 코드를 삭제하고 리팩토링해보자.
 
const [name, setName] = useState(""); const [birth, setBirth] = useState(""); const [country, setCountry] = useState(""); const [bio, setBio] = useState("");
 
const [input, setInput] = useState({ name: "", birth: "", country: "", bio: "", });
 

2. 이벤트 핸들러 수정

 
더 이상 존재하지 않는 함수를 삭제하고
공통으로 사용되는 상태 변경 함수를 활용하자.
 
먼저, name 프로퍼티의 값을 변경할 함수를 작성하자.
setInput 함수를 사용하여 name 프로퍼티의 값을
e.target.value 값으로 변경하자.
 
const onChangeName = (e) => { setInput({ name: e.target.value, }); };
 
하지만 여기까지만 적으면 굉장히 위험한 코드가 된다.
해당하는 이벤트가 발생했을 때 name 값이 변경되며
다른 프로퍼티의 값이 전부 날아갈 수 있기 때문이다.
 
따라서 작성해두었던 코드 위에
전개연산자를 사용해 input에 있던 기존 값을 뿌려주어야 한다.
 
const onChangeName = (e) => { setInput({ ...input, name: e.target.value, }); };
 
input의 값을 미리 뿌려주는 이유는,
해당하는 이벤트 핸들러가 실행됐을 때,
변경하고자 하는 값 외에 기존에 있던 값을
넣어주기 위함이다.
 
해당하는 정보를 미리 뿌려주지 않으면
이벤트가 실행될 때 다른 프로퍼티의 값은
사라지고 name 프로퍼티만 남게되기 때문이다.
 

 
마찬가지로 다른 이벤트 핸들러도 수정해주자.
 
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, }); };
 

3. value 변경

 
기존에 value에 넣어두었던 변수는 더 이상 존재하지 않는다.
 
따라서 input객체에 프로퍼티로 존재하는 이름으로 변경해주자.
 
return ( <div> <div> <input value={input.name} onChange={onChangeName} placeholder="이름" /> </div> <div> <input value={input.birth} onChange={onChangeBirth} type="date" /> </div> <div> <select value={input.country} onChange={onChangeCountry}> <option></option> <option value="kr">한국</option> <option value="us">미국</option> <option value="uk">영국</option> </select> </div> <div> <textarea value={input.bio} onChange={onChangeBio} /> </div> </div> ); };
 
이제, 상태가 잘 저장되고 있는 지 확인하기 위해
console에 input객체를 출력해보자.
 
const [input, setInput] = useState({ name: "", birth: "", country: "", bio: "", }); console.log(input);
 
사용자 입력에 따라 저장되고 있는 것을 확인할 수 있다.
 
notion image

4. 통합 이벤트 핸들러 만들기

 
이벤트 핸들러도 모두 같은 코드를 가지고 있어
이를 통합하여 사용할 수 있다.
 
합성 이벤트 객체에서 제공하는 e.target.name이라는 속성을 활용할 수 있다.
 
const onChange = (e) => { setInput({ ...input, [e.target.name]: e.target.value, }); };
 
하지만 합성 이벤트 객체에서 제공하는 name
수기로 입력하지 않으면 기본값이 빈문자열로
제공되기 때문에 각 입력폼에 name 속성을
작성해주어야한다.
 
return ( <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 name="country" value={input.country} onChange={onChange}> <option></option> <option value="kr">한국</option> <option value="us">미국</option> <option value="uk">영국</option> </select> </div> <div> <textarea name="bio" value={input.bio} onChange={onChange} /> </div> </div> );
 
Share article

clubnerdy