React 를 만지면서 useEffect 는 사실 1년 이상을 동거동락해왔다.
하지만 처음 강의를 들을 때 공부하거나 실무에서 그때그때 얻은 조각난 지식말고는 제대로 아는 게 없다는 것을 깨닫고 부끄러웠다.
그래서 리액트 공식문서 구버전과 신버전(beta) 을 참고하여 useEffect 에 대해서 조각난 퍼즐을 맞춰 정리해보았다.
React(90) useEffect 에 대해서 (공식문서 정리)
useEffect 는 리액트 16.8 에서 도입된 Hook(리액트의 내장함수)이다.
코드를 짜다보면 화면이 새로고침되거나(렌더링) 데이터가 뭐가 바뀔 때(업데이트),
어떤 함수가 실행되야 할 때가 있다. 얘는 그런 needs 가 탄생시킨 함수이다.
side effects 는 렌더 후에 일어나는 코드의 실행을 말하고,
Data fetching, setting up a subscription, and manually changing the DOM 같은 실행 등이 있다.
클래스형 컴포넌트 vs 함수형 컴포넌트
리액트의 라이프 사이클은 mount - update - unmount 로 구분할 수 있다.
컴포넌트도 그들의 인생이 있다. 파싱될 때 태어나 역할을 다하고 죽음을 맞는다.
mount 는 컴포넌트가 생성될 때의 상태이고, (유아기)
update는 컴포넌트가 업데이트될 때의 상태이고, (청년기)
unmount는 컴포넌트가 제거될 때 상태이다. (노년기)
클래스형 컴포넌트 일 때,
componentDidMount() 와 componentDidUpdate() 함수가 useEffect 의 역할을 한다.
한마디로 마운트 하거나 업데이트 할 때 실행해라 이거다. 근데 좀 불편하다. 하나의 effect 를 위해 두군데에다 넣어줘야 하기 때문이다.
함수형 컴포넌트 일 때,
클래스형 컴포넌트에서는 매번 렌더링 할때마다 함수를 실행하는 메소드는 없다. 여기서 useEffect 는 빛을 발한다.
useEffect() 를 통해 렌더나 업데이트시 document.title 이 동적으로 바뀐다.
Clean up 함수에 대해서
useEffect 에서 실컷 사용한 함수를 담아 고대로 return 해주면 다음 렌더 시 깨끗하게 제거하고 다시 시작한다.
DOM에서 컴포넌트가 제거 될 때 마지막으로 클린업함수로 지워주고 장렬히 전사하는 경우가 있고,
외부 데이터와 연관되는 로직의 실행을 위해 subscription을 set up 하고, 볼일다봤으면 clean up 하는 경우에 사용한다.
클래스형 컴포넌트의 클린업 함수
componentWillUnmount() 라는 함수를 통해 호출을 또 해줘야 했다. 같은 effect 의 실행과 제거를 위해 두번씩이나(?) 호출하다니 ...
함수형 컴포넌트의 클린업 함수
여기서는 useEffect 구문의 return 함수로 클린업해줄수 있는데, 화살표함수도 상관없다
클린업 함수 실행 순서
UseEffect 의 렌더 시 함수 동작방식은 다음과 같다.
#1 클린업 함수 실행 - remove old value
#2 셋업 함수 실행 - update new value
useEffect 에 대해서
• 렌더나 업데이트 후 useEffect() 안에 들어있는 함수를 실행한다.
• 얘도 Hook이라서 컴포넌트 내에 위치한다.
즉, 함수 스코프(컴포넌트) 안에 있기 때문에 상위 스코프의 변수나 함수 등을 기억한다. (클로저)
그래서 useEffect 안에서 자유롭게 state 나 setState 를 사용할수 있다.
• 렌더시 매번 실행된다. 이 점은 stale 한 상태를 피하고 state 값을 최신으로 유지할 수 있게 해준다.
즉, 매번 실행 === 매번 생성 과 같은 말을 의미한다.
렌더될 때마다 useEffect 와 내장함수는 매번 새로 만들어지고, 그로인해 함수의 state 값은 최신의 상태를 유지할 수 있게 된다.
• 얘도 hook 이라 컴포넌트 최상단에 위치해야 한다.
• StrictMode 가 on 이면, 첫 렌더가 돌때 useEffect 를 추가 실행한다.(stress-test를 위해)
• dependencies 가 객체나 함수일 때 필요 이상으로 실행 될 수 있다. 딱히 필요없는 객체나 함수는 디펜던시로 사용하지 말자.
• useEffect 는 브라우저가 화면을 그린 후(Paint) 업데이트 된다.
즉, useEffect 로 실행한 결과가 visualize 하다면 화면에 바로 반영되어 나오지 않는다는 말이다.
그럴 때는 useLayoutEffect 를 사용하는 것을 권장한다. (얘는 paint 할때 실행된다)
재작년에 정리해봤던 관련 포스팅이다. (이렇게 몰랐다니🥲)
제한적으로만 알던 useEffect 를 다시한번 공부할 수 있어서 정말 좋았다.
ref:
https://reactjs.org/docs/hooks-effect.html
https://beta.reactjs.org/reference/react/useEffect#useeffect
'React' 카테고리의 다른 글
React(92) useRef 알아보기 (공식문서 정리) (0) | 2023.02.01 |
---|---|
React(91) 탭 클릭시 지정 영역으로 스크롤 이동 / 스크롤시 해당 탭 자동선택 (0) | 2023.01.25 |
React(89) 글 작성시간 계산함수 만들기 (몇분전/몇시간전/몇일전) (0) | 2022.12.28 |
React 실행오류 - rendered fewer hooks than expected (feat. Hook의 규칙) (0) | 2022.11.30 |
React(88) KST 에서 UTC 로 시작일/종료일 변환하기 (feat.moment) (0) | 2022.11.17 |
댓글