multiple states
하나의 컴포넌트는 하나 이상의 state를 가질 수 있다. 가지고 있는 state 중에 하나라도 값이 업데이트 되면, re-rendering이 발생한다.
import { useState } from 'react';
const NewExpenseForm = (props) => {
const [title, setTitle] = useState('');
const [amount, setAmount] = useState('');
const [date, setDate] = useState('');
const titleChangeHandler = (e) => {
setTitle(e.target.value);
};
const amountChangeHandler = (e) => {
setAmount(e.target.value);
};
const dateChangeHandler = (e) => {
setDate(e.target.value.split('-'));
};
return (
<form>
<!-- input, button...-->
</form>
);
}
- 사용자에게 title, amount, date 값을 입력받는 세 개의 input이 있다.
- 이 값을 독립적으로 관리하려면 3개의 state를 이용할 수 있다.
- ??? 코드가 반복되고 있기는 한데, 여기서 더 간결한 코드를 작성할 수 있는지 모르겠음
single state
spread operator
세 개의 input 데이터를 하나의 state로 묶어서 관리할 수도 있다.
const NewExpenseForm = (props) => {
const [userInput, setUserInput] = useState({title:'', amount:'', date:''});
const titleChangeHandler = (e) => {
setUserInput({...userInput, title: e.target.value}); // spread & over-ride
};
const amountChangeHandler = (e) => {
setUserInput({...userInput, amount: e.target.value});
};
const dateChangeHandler = (e) => {
setUserInput({...userInput, date: e.target.value.split('-'));
};
return (
<form>
<!-- input, button...-->
</form>
);
}
- state의 초기값은 객체가 된다.
- setExpense({ ...userInput, title: e.target.value })
- spread 연산자를 이용해 userInput 객체의 모든 property를 복사하고, title property의 값만 덮어 씌워서 state를 업데이트 한다.
- amount, date에 대해서도 동일하게 진행한다.
- set 함수는 즉각적으로 state를 업데이트 하는 것이 아니라 업데이트를 예약하는 함수이기 때문에, userInput 객체가 최신 상태임을 항상 보장할 수는 없다. => prevState의 필요성
previous state | prevState
const titleChangeHandler = (e) => {
setUserInput((prevState) => {
return {...prevState, title: e.target.value};
});
};
- 리액트에서 제공하는 prevState는 가장 최신의 state 값을 반환할 것을 보장해 준다.
- set 함수의 인자로 콜백함수를 전달한다.
- 콜백함수는 prevState를 인자로 받고, 업데이트 될 값을 반환한다.
+) 위의 예제에서 여러 개의 state를 사용할지, 하나의 state를 사용할지를 결정하는 것은 preference의 문제이다.
+) 다만 하나의 state를 사용할 때에는 prevState를 이용하는 것이 안전하다.
+) onSubmit
const submitHandler = (e) => {
e.preventDefault();
/*titleInput 값을 이용해서 어떤 일을 한다*/
setTitleInput(''); // input 창을 초기화한다
};
<input
type='text'
name='title'
id='title'
value={titleInput}
onChange={titleChangeHandler}
/>
- value={titleInput} | form이 실제로 제출되었을 때 서버 측에서 유용하게 사용할 수 있다.
- input에서 사용자가 입력한 값을 titleInput으로 설정하고, 그 titleInput을 다시 input의 value로 설정하기 때문에 " 2 way binding "이라고 부른다.
'Study > React' 카테고리의 다른 글
Conditional contents (0) | 2022.06.17 |
---|---|
Dynamic List (0) | 2022.06.17 |
Event & useState (0) | 2022.06.16 |
JSX (0) | 2022.06.16 |
Component & Props (0) | 2022.06.16 |