리액트 처음부터 기초를 다지던 중, event handling을 공부하다가 state 관련해서 제대로 정의를 할 수 없다는 것을 깨닫고 setState부터 공부해보았다.
리액트의 함수형 컴포넌트 내에서 상태를 관리하기 위해 사용하는 hooks인 useState()를 통해 반환되는 함수
import react, {useState} from "react";
import "./App.css";
export default function App() {
const [number, setNumber] = useState(1);
const addOne = () => setNumber(number+1); //1을 더해주는 함수
const subtractOne = () => setNumber(number - 1); //1을 빼주는 함수
const multiplyBy2 = () => setNumber(number*2); //2를 곱해주는 함수
const multiplyBy2AndAddBy1 = () => {
multiplyBy2();
addOne();
}; // 2를 곱하고 1을 더해주는 함수
return (
<div className="outer-wrapper">
<h1>Number : {number}</h1>
<div className="btn-wrapper">
<button onClick={addOne}>+ 1</button>
<button onClick={subtractOne}>- 1</button>
<button onClick={multiplyBy2}>*2</button>
<button onClick={multiplyBy2AndAddBy1}>*2 + 1</button>
</div>
</div>
);
};
위의 예시에서, addOne 함수, subtractOne 함수, multiplyBy2 함수는 제대로 동작하지만,
multiplyBy2AndAddBy1 함수를 실행시키면 addOne()만 실행된다. (문제 발생)
💡 setState()는 비동기이기 때문!!⏩ 어쨌든 setState()는 비동기 방식인데, 효율성을 위해 setState()는 모든 object들을 merging한 후 *한번만* 호출한다.변경되기 전의 state 값과 변경된 후의 state 값을 비교
( = 현재의 state 값으로 만든 element tree와 업데이트된 state값으로 만든 element tree를 비교)
한 후에, 최종적으로 변경된 부분이 있으면 그 부분만 DOM에 적용
즉, 위의 예시처럼 setState()를 연속적으로 사용했을 때에는 마지막에 사용된 함수만 적용되는 것처럼 보이는 것!
setState()를 연속적으로 사용할 수 있게 하는 방법을 알아보자. (두번째 코드 참고)
//변경 전
const addOne = () => setNumber(number+1);
const subtractOne = () => setNumber(number - 1);
const multiplyBy2 = () => setNumber(number*2);
const multiplyBy2AndAddBy1 = () => {
multiplyBy2();
addOne();
};
//변경 후
const addOne = () => setNumber(number => number+1);
const subtractOne = () => setNumber(number => number - 1);
const multiplyBy2 = () => setNumber(number => number*2);
const multiplyBy2AndAddBy1 = () => {
multiplyBy2();
addOne();
};
위의 코드에서는 multiplyBy2AndAddBy1()을 실행하면 addOne()만 실행되지만,
아래의 코드에서는 multiplyBy2AndAddBy1()을 실행하면 multiplyBy2()와 addOne() 모두 잘 동작한 결과를 볼 수 있다.
인자를 준 뒤에 state를 반환하도록 하였다.
addOne()함수 : number를 인자로 주고, number+1이라는 state를 반환하는 함수
setNumber(number => number+1)
넘겨받은 인자의 함수를 Queue에 저장해두는 방식이다.
위의 예시에서는 multiplyBy2() 함수를 먼저 실행해주고, number*2라는 새로운 값을 반환한 뒤 그 다음 함수(addOne)의 인자로 넘겨주는 것이다.