해당 단계에서는 한 개의 폼이 아닌 두개, 세개 그 이상의 폼을 다루는 방법에 대해 알아본다.
유저가 입력할 수 있는 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
를 통하여 해당 입력값에 조건을 걸어 입력하지 않으면 포커스를 해주는 기능에 대해 알아보자