setState(prev => !prev);
// 예: 이전값이 false가 들어오면 true를 반환하고,
// true가 들어오면 false를 반환합니다.
이전 값을 이용해서 다음 값을 set해 줄 때 사용하기 좋습니다.
const App = () => {
console.log("App render start"); // 1번째
const [state, setState] = React.useState(() => {
console.log("App useState"); // 2번째
});
// useEffect empty deps // 4번째 (선언순으로 불립니다.)
// useEffect no deps // 5번째 (선언순으로 불립니다.)
// useEffect [state] // 6번째 (선언순으로 불립니다.)
} // App end
ReactDOM.render(<App />, rootElement);
console.log("App render end"); // 3번째
실행 결과
사이드 이펙트이기 때문에 일단 다 그려지고 나서 동작합니다.
const Child = () => {
console.log(" Child render start"); // 4번째
const [state, setState] = React.useState(() => {
console.log(" Child useState"); // 5번째
});
// useEffect empty deps // 7번째
// useEffect no deps // 8번째
// useEffect [state] // 9번째
console.log(" Child render end"); // 6번째
return (
......
);
}
const App = () => {
console.log("App render start"); // 1번째
const [state, setState] = React.useState(() => {
console.log("App useState"); // 2번째 (초기 렌더링시에만 실행)
});
// useEffect empty deps // 10번째 (초기 렌더링시에만 실행)
// useEffect no deps // 11번째
// useEffect [state] // 12번째
console.log("App render end"); // 3번째
return (
......
<Child />
......
);
} // App end
ReactDOM.render(<App />, rootElement);
UseEffect의 호출 시점을 잘 인지하고 있어야합니다.
우리가 원하는 동작을 원활한 타이밍에 만들지 못 할 수도 있습니다.
위에서 정리(clean-up)가 필요하지 않은 side effect를 보았지만, 정리(clean-up)가 필요한 effect도 있습니다. 메모리 누수가 발생하지 않도록 정리(clean-up)하는 것은 매우 중요합니다.
React.useEffect(() => {
console.log("App useEffect, [show]");
return () => {
console.log("App useEffect [Cleanup], empty deps");
};
}, [show]);
우리는 이 클린업에 이런 동작을 추가할 수 있습니다.
unmount 전에 local Storage를 지우고 간다