useState
리액트는 최초 렌더링될때 모든 jsx 컴포넌트를 한번씩 읽는데, 읽고 난뒤에는 아무리 그뒤에 데이터(or value)를 바꿔준다고 해서 재렌더링되지는 않는다.
리액트의 입장에서는 리렌더링 하지않는이상 값이 바뀌었다는것을 알수없어서 업데이트 하지 않는것인데 그렇다면 state의 값을 업데이트하기위해 어떻게 리액트를 리렌더링 시킬까?
만약 당신이 유동적이고 유저가 사용하는 인터페이스에 반영되는 데이터를 가지고있다면 state가 필요하다 왜냐하면 일반적인 변수는 state를 바꿀수없기때문이다. 그러나 당신은 값(values)를 만들고 바꿀수있다. 값들이 바뀔때 리액트는 오직 state가 입력된 컴포넌트를 다시 읽을 것이다.(다른 컴포넌트들은 변하거나 리렌더링 되지 않는다)
state를 useState 훅을 이용해서 바꾸려고(입력하려고) 한다면 항상 두가지 값(values)이 따라온다
state: value itself
과 setState : value updating function(update whenever the State should change)
.
(state는 그냥 초기 이름이다.어떤이름이든 상관없음!)
첫번째 요소: JSX 코드로 보여지는 state 값. 예시) <h2>{title}</h2>
curly braces 안에만 적어두면 나머지는 리액트가 알아서 state 가 바뀔때마다 컴포넌트를 리렌더링하고 jSX 코드를 재평가한다.
1.Multi-state approach
const [enteredTitle,setEnteredTitle] = useState("");
const [enteredAmount,setEnteredAmount] = useState("");
const [enteredDate,setEnteredDate] = useState("");
-------------------- state 사용힐때 -------------------------
const titleChangeHandler = (event) => {
setEnteredTitle(event.target.value);};
const amountChangeHandler = (e)=> {
setEnteredAmount(e.target.value);};
const dateChangeHandler = (e)=> {
setEnteredDate(e.target.value);};
=> state value 모두 따로따로 써주기
const [userInput,setUserInput]= useState({
enteredTitle:"",
enteredAmount:"",
enteredDate:"",
});
-------------------- state 사용할때 -------------------------
const titleChangeHandler = (e) => {
setUserInput({...userInput, enteredTitle: e.target.value});
};
const amountChangeHandler = (e)=> {
setUserInput({...userInput,enteredAmount: e.target.value,});
};
const dateChangeHandler = (e)=> {
setUserInput({...userInput,enteredDate: e.target.value,});
};
1번과 2번 모두 같은것을 말하고있다
2번처럼 사용시 주의할점 ) 여러 state를 함께 다루다 보니 한개의 state값을 바꾸게 될때 나머지 state값들도 잃지않기위해 복사해서 같이 적어줘야한다.다시말해, 이전 state에 이미 있던 values들을 복사해오고(스프레드 문법으로 원래있던것도 적어주고) 나머지 바뀌는 state값을 업데이트해서 덮어씌워준다.
더 나은 방법인 이유: 리액트는 state가 바뀌었다고 당장 업데이트 하지는 않는다. 이론적으로 만약 지금 내가 2번 방법을 써서 엄청나게 많은 state값들을 동시에 업데이트 한다고하면 state값들은 예전의 정확하지않은 state값에서 업데이트 될수도 있다 => 정확도가 떨어짐
그래서 3번째 방법을 쓴다면 state값 업데이트시 inner function에 ((prevState)=>{}) prevState를 씀으로써 리액트가 모든 state 업데이트스케쥴을 항상 기억하면서 최신의 state에서 다시 state를 업데이트 할수있게된다. 그래서 이방법이 최신의 state에서 업데이트 하는거라고 재확인하면서 state값을 바꿀수있는 더 안전한 방법이다. 만약 당신이 state값을 업데이트 할때 이전 state 값에 영향을 받는다면 이 function form((prevState) =>{})을 쓰면 좋다!