일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- springboot
- ReactHooks
- React
- frontend
- Spring
- 오블완
- hook
- Gin
- javascript
- 티스토리챌린지
- test
- tanstackquery
- storybook
- RTK
- satisfiles
- golang
- Redux
- designpatterns
- go
- JPA
- backend
- typescript
- 웹애플리케이션서버
- Chakra
- java
- JavaSpring
- react-hook-form
- css
- component
- Today
- Total
bkdragon's log
useEffect 친해지기 1 본문
순수성과 Side Effect
순수성과 Side Effect는 대비된다. React의 컴포넌트는 순수성을 가진다. 동일한 Props를 받으면 늘 동일한 Jsx를 반환한다. 즉, React 렌더링 과정에서 Side Effect는 발생 되어서는 안된다.
useEffect
그래서 Side Effect와 React의 렌더링을 분리하기 위해 useEffect가 등장했다. useEffect는 렌더링 과정에서 커밋(재조정 결과를 dom에 반영) 후에 작동함으로 Side Effect와 렌더링을 분리한다. 그리고 useEffect는 컴포넌트의 생명주기 (mount, update, unmount)에 간섭할 수도 있다.
기본 사용법
function MyComponent () {
useEffect(() => {
return () => {
}
}, [])
return <div />
}
첫 번째 인자로 callback, 두 번째 인자로 의존성 배열을 받는다.
- 의존성 배열이 비어있는 경우.
- 의존성 배열이 비어있는 경우 callback은 컴포넌트가 mount 될 때 한번만 실행된다.
- callback 내부의 return 함수
- 컴포넌트가 unmount 될 때 실행된다.
- 의존성 배열에 값이 있는 경우
- 컴포넌트가 mount 될 때 실행되고 의존성 배열의 값이 변경되는 경우에도 실행된다.(update)
cleanup
useEffect를 통해 Side Effect를 다룰 때 초기화 해줘야하는 상황이 있을 수 있다. 예를 들어 addEventListener를 통한 브라우저 이벤트 추가이다. 이벤트를 제거해주지 않는다면 React 입장에선 상관 없을 수 있으나 브라우저에겐 부담이 될 수 있다.
useEffect(() => {
function handleScroll(e) {
console.log(window.scrollX, window.scrollY);
}
window.addEventListener('scroll', (e) => {
console.log('connect')
handleScroll(e)
});
return () => window.removeEventListener('scroll', (e) => {
consol.log('disconnect')
handleScroll(e)
});
}, []);
return 함수에서 removeEventListener 를 통해 이벤트를 제거해주고 있다.
근데 사실 이때 cleanup을 해줘야하는 한가지 이유가 더 있다. 초반에 언급했듯 React 컴포넌트는 순수성을 지니는데 이를 검사하기 위해 React Strict mode에서는 컴포넌트를 두 번 마운트 한다. 순수하다면 두 번 모두 같은 jsx를 반환할 것이기 때문이다.
콘솔을 확인해보면 다음과 같을 것이다.
connect
disconnect
connect
첫 번째 마운트에 연결되었다가 연결이 해제되고 두 번째 마운트에 다시 연결이 되는 것이다. 이는 개발환경에서만 유효하고 빌드 후엔 유효하지 않다. 그러니 strict mode를 끄기보단 cleanup을 알맞게 해주는 것이 좋은 선택이라고 볼 수 있다.
의존성 배열의 값이 변경되면
의존성 배열이 값이 변경되면 useEffect의 callback은 다시 실행된다. 이때 return도 마찬가지이다.
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => {
connection.disconnect();
};
}, [roomId]);
위 useEffect는 roomId에 의존성이 있다. 컴포넌트 마운트부터 roomId가 변경되었을 때 실행되는 동작을 순서대로 설명하면 다음과 같다.
- 컴포넌트가 마운트되고 초기값에 해당하는 roomId로 연결된다.
- 연결이 해제된다.
- 다시 연결된다. (strict mode 때문이다.)
- roomId가 변경되면, 기존 roomId로 연결되어있던 것이 연결이 해제된다. 즉 return 함수가 실행된다.
- 새로운 roomId로 새롭게 연결한다.
포인트는 값이 변경되면 기존의 사이클이 끝나고 새로운 사이클이 시작되는 것이다.
반응형 값
useEffect는 반응형 값에만 반응한다. 반응형 값은 Props나 state 또는 이들로 부터 계산된 값을 의미한다.
useEffect의 기본적인 사용법과 개념을 알아보았다. 친해지기 2에서는 실전에서 사용해볼 수 있는 예제를 공부해서 소개해보겠다.
'React' 카테고리의 다른 글
Streaming SSR (0) | 2023.08.21 |
---|---|
Server Component (0) | 2023.08.21 |
반복되는 요소 렌더링 최적화 하기 (0) | 2023.08.05 |
React 이벤트 위임 (0) | 2023.07.30 |
클로저와 useState (0) | 2023.07.10 |