상태를 관리할 수 있게 도와주는 HOOK
상태란?
동적인 값 ==> 변경가능한 값
예시
const [state, setState] = React.useState(initialState)
// state은 상태값을 담고있는 변수
// setState 상태를 갱신하는 함수
import React from "react";
import "./styles.css";
export default function App() {
const [syncState, setSyncState] = React.useState(1);
return (
<div className="App">
<h1>Hello Asynchronism and Synchronism</h1>
<h2>press synchronism buttom !</h2>
<div>{syncState}</div>
<div>
<input
type="button"
value="add one"
onClick={() => {
setSyncState(syncState + 1);
}}
/>{" "}
<input
type="button"
value="minus one"
onClick={() => {
setSyncState(syncState - 1);
}}
/>
</div>
</div>
);
}
버튼을 누르면 1이 더하기되거나 마이너스되는 간단한 로직
그럼 여기서 숫자 1을 5번 더하는 로직을 짜면 어떻게 움직일까 ?
import React from "react";
import "./styles.css";
export default function App() {
const [syncState, setSyncState] = React.useState(1);
return (
<div className="App">
<h1>Hello Asynchronism and Synchronism</h1>
<h2>press asynchronism buttom !</h2>
<div>{syncState}</div>
<div>
<input
type="button"
value="5 times add in a row. (wrong working) "
onClick={() => {
setSyncState(syncState + 1);
setSyncState(syncState + 1);
setSyncState(syncState + 1);
setSyncState(syncState + 1);
setSyncState(syncState + 1);
}}
/>{" "}
<input
type="button"
value="5 times minus in a row. (wrong working)"
onClick={() => {
setSyncState(syncState - 1);
setSyncState(syncState - 1);
setSyncState(syncState - 1);
setSyncState(syncState - 1);
setSyncState(syncState - 1);
}}
/>
</div>
</div>
);
}
상식상으로는 버튼을 눌렀을 때
syncState 은 한번에 5가 더해지거나 5가 빼져야 정상이다
하지만 버튼을 누르면 1만 변경된다.
이유는 useState이 비동기적으로 실행 되기 때문이다.
setSyncState으로 상태를 변경하기 전에 두번째 setSyncState가 실행되기 때문이다.
그럼 어떻게 동기적 실행을 할 수 있을까?
먼저 로직을 봐보자
import React from "react";
import "./styles.css";
export default function App() {
const [syncState, setSyncState] = React.useState(1);
return (
<div className="App">
<h1>Hello Asynchronism and Synchronism</h1>
<h2>press asynchronism buttom !</h2>
<div>{syncState}</div>
<div>
<input
type="button"
value="5 times add in a row. (right working) "
onClick={() => {
setSyncState((prev) => {
return prev + 1;
});
setSyncState((prev) => {
return prev + 1;
});
setSyncState((prev) => {
return prev + 1;
});
setSyncState((prev) => {
return prev + 1;
});
setSyncState((prev) => {
return prev + 1;
});
}}
/>{" "}
<input
type="button"
value="5 times minus in a row. (right working)"
onClick={() => {
setSyncState((prev) => {
return prev - 1;
});
setSyncState((prev) => {
return prev - 1;
});
setSyncState((prev) => {
return prev - 1;
});
setSyncState((prev) => {
return prev - 1;
});
setSyncState((prev) => {
return prev - 1;
});
}}
/>
</div>
</div>
);
}
바로 setState에 콜백함수를 넣어주는 것이다.
setSyncState((prev) => {
return prev - 1;
});
으로 prev는 이전값 바꿀 값을 리턴하면 setState은 동기적으로 실행이 된다.
프로젝트를 진행하다보면 useState의 값이 원하는 상태값으로 변하지 않을 때가 종종 생긴다. 이럴 경우 useState의 동기 비동기성을 생각하며 로직을 짜 보자