해당 단계에서는 한 개의 폼이 아닌 두개, 세개 그 이상의 폼을 다루는 방법에 대해 알아본다.
유저가 입력할 수 있는 input, 여러 줄을 적을 수 있는 textarea, 옵션을 정할 수 있는 select에 대해서 알아보자
여기서 추가로 알아야 할 것은 폼(Form)을 다루기 위해선 onChange를 사용한다는 것이다.
입력값을 제어하기 위해 onChange에 대해서 알아보자.
편의를 위해 생략되는 코드가 있음을 양해를 구한다.
const [input, setInput] = useState('');
<input value={input} onChange={(e) => {
console.log(e);}}/>
일단 해당 콘솔창을 보게되면 여러가지가 뜨는데 가장 보이는 것은 InputEvent + Object라는 것
그럼이 input에서의 입력값을 알기 위해선 e.target.value 값에 접근을 해야한다.
<input value={input} onChange={(e) => {
console.log(e.target.value);}}/>
으로 변경을 하게되면 입력을 했을 때 한 글자씩만 콘솔에 뜨는것을 볼 수 있다.
내가 원하는 것은 전체 입력값인데,,,,
내가 입력한 값을 받기 위해 setInput을 통해 얻어보자
폼에서 onChange 이벤트가 일어나면 해당 e.target.value 를 통해 input 값을 읽을 수 있지만 그 순간의 변화만 읽어주기에 setInput함수에 e.tartget.value를 넘겨주어 전체 입력 값을 얻을 수 있다.
<input value={input} onChange={(e) => {
console.log(e.target.value);
setInput(e.target.value);}}/>
만약 해당 페이지가 회원가입 페이지, 비밀번호 찾기 등 입력폼이 많으면?
const [a,setA] = useState('');
...
...
...
const [z,setZ] = useState('');
.... 또 다시 만난 무한굴레 🥵
const [state, setState] = useState({
input: '',
textarea: '',
select: 1,
});
return (
<div>
<h2>입력 폼 공부하기</h2>
<div>
<input
value={state.input}
onChange={(e)=>{
setState({
input: e.target.value,
textarea: state.textarea,
select: state.select
})
}}
/>
</div>
<div>
<textarea
value={state.textarea}
onChnage={(e)=>{
setState({
input: state.input,
textarea: e.target.value,
select: state.select
})
}}
/>
</div>
<div>
<select
value={state.select}
name="select"
onChange={(e) => {
setState({
input: state.input,
textarea: state.textarea,
select: e.target.value
});
}}
>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
</div>
</div>
)
setState에서 input값이 변하는데 textarea값도 같이 변경되면 안된다.input에 입력을 할 때엔 textarea의 값은 ''가지게 된다.어떤 점이 아쉬운가? -> 전 보다는 조금 관리가 쉬워진 것은 맞지만, setState에서 하지 않는것에 대한 값을 계속 불러야 한다는 점이다.
...스프레드 연산자를 사용하여 해당코드 수정하기
import { useState } from 'react';
const UserForm = () => {
const [state, setState] = useState({
input: '',
textarea: '',
select: 1,
});
return (
<div className="UserForm">
<div>
<input
value={state.input}
onChange={(e) => {
setState({
...state,
input: e.target.value,
});
console.log(e.target.value);
}}
/>
</div>
<div>
<textarea
value={state.textarea}
onChange={(e) => {
setState({
...state,
textarea: e.target.value,
});
console.log(e.target.value);
}}
></textarea>
</div>
<div>
<select
value={state.select}
name="select"
onChange={(e) => {
setState({
...state,
select: e.target.value,
});
console.log(e.target.value);
}}
>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
</div>
</div>
);
};
export default UserForm;
여기서 조금 주의해야할 점은
(...)스프레드 연산자를 사용해서 기존state를 불러오는데 이게 순서가 뒤집어 지면
바뀐state를 기존state로 덮게 된다. 그렇게 되면 아무리 값을 입력해도 바뀐 값에 대해서 알지 못할 것이다.
위의 코드는 지금 태그 안에서 onChnage를 통해
state를 관리하고 있는데 이렇게 되면 코드가 너무 길어지기에state를 관리하는 함수를 만들어서 코드를 줄여보자
state의 변화를 관리하는 handleChnageState 함수를 만든다.
const handleChnageState = (e)=>{
setState({
...state,
"변경 되는 값":e.target.value;
})
}
위의 코드를 보면 변경되는 값의 변화를 체크하면 되기에 해당 이벤트가 일어나는 폼의 이름만 알면 되기에 "변경 되는 값" -> e.target.name으로 변경하여 코드를 수정해보자
import { useState } from 'react';
const UserForm = () => {
const [state, setState] = useState({
input: '',
textarea: '',
select: 1,
});
const handleChnageState = (e) => {
setState({
...state,
[e.target.name]: e.target.value,
});
console.log(e.target.value);
};
return (
<div className="UserForm">
<div>
<input name="input" value={state.input} onChange={handleChnageState} />
</div>
<div>
<textarea name="textarea" value={state.textarea} onChange={handleChnageState}></textarea>
</div>
<div>
<select name="select" value={state.select} onChange={handleChnageState}>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
</div>
</div>
);
};
export default UserForm;
확실히 한 눈에 onChnage를 했을때 어떠한 행동을 하는지 보여서 깔끔해 진 것 같다
const handleSubmit = () => {
console.log(state)
}
<button onClick={handleSubmit}></button>
해당 버튼을 누르게 되면 이제 다음과 같은 결과를 얻을 수 있다.

다음 장에서는
useRef를 통하여 해당 입력값에 조건을 걸어 입력하지 않으면 포커스를 해주는 기능에 대해 알아보자