useEffect가 호출되는 시점에 대해 설명해 주세요.
useEffect 는 마운트 언마운트 업데이트시에 실행된다고 볼 수 있을 것 같다. 의존성 배열을 주어 의존성 값이 변경되었을때 실행할 수 있는데 해당 배열을 주지 않으면 최초 실행시에만 작동한다. 또한 언마운트시에 실행하고 싶으면 return 값을 통한 클린업 함수 호출이 가능할것이다.
다만 리액트에서 안티패턴으로 useEffect 를 통한 단순 마운트시의 동작을 위해 사용하는건 잘못된 방식이다.
처음한번만 실행되어야 하는 경우 함수등으로 동작시켜야 하며 주의해야한다
useEffect는 컴포넌트의 특정 시점에 자동으로 호출되는 훅으로, 크게 컴포넌트가 마운트 , 업데이트, 언마운트 되는 시점에 호출된다.
먼저 useEffect 는 컴포넌트가 마운트될 때, 즉 처음 렌더링되고 나서 호출된다. 이때 데이터의 초기화나 외부 API호출 구독 설정등의 작업을 실행할 수 있다. useEffect는 컴포넌트가 처음 마운트 될때 필요한 초기 작업을 수행할 수 있도록 해준다.
또한, useEffect 는 의존성 배열에 지정된 갑싱 변경될 때 마다 다시 호출된다. 이때 useEffect의 return 값으로 지정된 클린업 함수가 이전 props 및 state와 함께 먼저 호출된 후, 본문의 실행 로직이 업데이트된 props및 state와 함께 실행된다.
두번째 인자로 주어지는 의존성 배열은 useEffect가 어떤 상태나 props의 변화에 반응할지를 결정한다. 예를 들어 useEffect(()=>{...}, [count]) 처럼 count 상태가 의존성 배열에 있을 경우, count 값이 변경될 때마다 useEffect가 호출됩니다. 이를 통해 특정 상태나 props가 변경될 때마다 필요한 동작을 수행하도록 할 수 있으며, 컴포넌트의 변화에 따라 동적으로 실행되는 로직을 설정할 수 있습니다.
단, 의존성 배열을 넘기지 않을 경우 매 렌더링마다 호출됩니다.
마지막으로, 컴포넌트가 언마운트될 때 useEffect의 return 값으로 지정된 클린업 함수가 호출됩니다. 이 정리 함수를 이용하여 이벤트 리스너 제거, 타이머 해제, 구독 취소등의 작업을 수행할 수 있습니다. 이를 통해 useEffect를 통해 발생한 부수효과를 정리하는 것이다.
요약하자면, useEffect는 컴포넌트가 처음 렌더링된 후, 의존성 배열의 값이 변경될 때, 그리고 컴포넌트가 언마운트될 때 호출된다.
답변에 대한 피드백 :
useEffect vs useLayoutEffect
useEffect: 브라우저 페인트(화면그리기)가 끝난 후 실행 -> 사용자에게 깜빡임 없는 부드러운 렌더링
useLayoutEffect: DOM이 업데이트된 직후, 페인트되기 전에 동기적으로 실행 -> 레이아웃 계산/DOM 읽기 쓰기 작업에 적합.
이에 DOM 크기를 측정하거나 스크롤 위치의 에저에 사용하면 좋음
서버컴포넌트와 클라이언트 컴포넌트
nextjs 에서 servercomponent 사용시 useEffect 사용이 불가능하다. 클라이언트에서만 실행되는 훅.
데이터 fetching 은 useEffect 보다는 server component + fetch 혹은 react query (tanstack) 로 위임하는게 좋다.
useEffect 는 브라우저에서만 필요한 사이드 이팩트에 집중해야 함 (리스너, 애니메이션, 추적)
상태 동기화 문제
useEffect 안에서 사용하는 변수는 렌더 시점의 값이 클로저로 캡처
이때문에 최신이 아닌 옛날 상태를 참조하는 문제 (stale closure)
의존성 배열을 정확히 넣어야 해결이 된다.