일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- react hook
- React 고급 안내서
- background tab
- background: url
- next13 head
- react-helmet
- context
- React18
- notFound()
- hook
- codingtest
- React 18
- Nextjs
- background setttimeout
- Next13
- React 18 Nextjs
- background setInterval
- React API 참고서
- 고급안내서
- React 공식문서
- Babel
- RTK Query
- CSS
- Nextjs React 18
- Programmers
- react
- getUTCDate
- Render Props
- React 고급안내서
- Javascript
- Today
- Total
akjfal
Effect Hook 사용하기 본문
useEffect는 class에서 componentDidMount, componentDidUpdate, componentWillUnmount가 합쳐진 방식이라고 생각하면 된다.
React에는 두 종류의 side effects가 존재하는데 clean-up이 필요한 것과 필요 없는 것 두가지가 있다.
clean-up이 필요 없는 Effects
class형에서 어떠한 데이터를 업데이트 하기 위해서는 컴포넌트가 방금 마운트 되엇는지(componentDidMount), 업데이트되었는지(componentDidUpdate)에 상관없이 모든 동작을 수행해줘야 할 수도 있습니다.
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
componentDidMount() {
document.title = `You clicked ${this.state.count} times`;
}
componentDidUpdate() {
document.title = `You clicked ${this.state.count} times`;
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
만약 위 코드에서 componentDidMount가 없으면 처음 렌더링 되었을 때 title이 기본 값인 상태가될 것이고, componentDidUpdate가 없으면 버튼을 눌렀을 때 title이 바뀌지 않을 것입니다.
따라서 같은 함수를 중복으로 적어줘야 하는 경우가 생기게 됩니다.
하지만 useEffect의 경우에는 한번에 처리가 가능합니다.
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useEffect가 하는일
컴포넌트가 렌더링 된 이후에 작동해야 하는 함수(effect)를 기억했다가, DOM 업데이터 이후 불러와 실행합니다.
useEffect를 컴포넌트 안에서 불러내는 이유
effect를 통해서 컴포넌트 내부의 state나 props를 접근해서 처리 할 수 있기 때문입니다.
useEffect는 렌더링 이후 매번 수행 되나요?
기본적으로 처음가 모든 업데이트에서 수행되지만, 의존성 값을 통해서 조절 할 수 있습니다. class의 마운팅과 업데이트라는 생각은 이제 버리시고, effect를 렌더링 이후에 발생시킨다. 라고 생각하시면 됩니다.
useEffect(callback, [dependency])
좀 더 깊은 설명
- useEffect에 전달되는 callback 함수는 모든 렌더링에서 다른 함수입니다. 이유는 내부의 값이 업데이트 되었는지 등 사이트 이펙트를 방지하기 위해서 의도된 방식이기 때문입니다.
- componentDidMount, componentDidUpdate와 달리 useEffect의 effect는 브라우저가 화면 업데이트 하는 것을 막지 안항 반응성을 향상시킵니다.
Clean-up을 이용하는 Effects
만약 컴포넌트가 언마운트 될 때 메모리 누수 방지를 위해서 setTimeout을 해지하는 등의 작업이 필요한 경우가 있습니다.
class FriendStatus extends React.Component {
constructor(props) {
super(props);
this.state = { isOnline: null };
this.handleStatusChange = this.handleStatusChange.bind(this);
}
componentDidMount() {
ChatAPI.subscribeToFriendStatus(
this.props.friend.id,
this.handleStatusChange
);
}
componentWillUnmount() {
ChatAPI.unsubscribeFromFriendStatus(
this.props.friend.id,
this.handleStatusChange
);
}
handleStatusChange(status) {
this.setState({
isOnline: status.isOnline
});
}
render() {
if (this.state.isOnline === null) {
return 'Loading...';
}
return this.state.isOnline ? 'Online' : 'Offline';
}
}
위의 코드에서도 componentDidMount와 componentWillUnmount를 통해서 컴포넌트가 처음 만들어질 때와 사라질 때 동작을 지정해주고 있습니다.
import React, { useState, useEffect } from 'react';
function FriendStatus(props) {
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
// effect 이후에 어떻게 정리(clean-up)할 것인지 표시합니다.
return function cleanup() {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
if (isOnline === null) {
return 'Loading...';
}
return isOnline ? 'Online' : 'Offline';
}
이를 useEffect에서는 함수를 return 시켜줘서 동작 하게 합니다.
이러한 함수 반환을 clean-up이라 부릅니다.
componentUnMount와 동일하게 컴포넌트의 파운트가 해제될 때 실행됩니다.
effect가 업데이트 마다 실행되는 이유
class형에서는 내부 값들이 업데이트 되었을 때 실행되도록 처리해주기 위해서 componentDidUpdate를 사용해주고 있습니다. 이를 사용하지 않으면 값이 바뀐 것을 대처할 수 없기 때문입니다. 하지만 effect가 업데이트마다 실행되고, 새로운 함수들을 실행 시켜주므로써 일관성을 유지 해줄 수 있습니다.
내부 동작 방식을 보면
- 처음 데이터 값 렌더링 {state : 100} state == 100이라고 가정
- effect 실행
- 데이터 값 업데이트 {state: 200} 으로 변경
- 기존 effect를 clean-up (state가 100인 effect)
- 신규 effect 실행(state가 200인 effect)
- 마운트 해제
- 기존 effect를 clean-up (state가 200인 effect)
방식으로 흘러가서 일관성을 유지해줍니다.
성능 최적화 시키기
아마 useEffect를 사용하시면서 대다수는 []를 사용했을것입니다. []의 경우에는 배열안에 들어가 있는 값들을 비교해서 effect를 실행 여부를 결정합니다.
또한 배열안에 있는 값들중 하나라도 변경시 effect는 동작하며, clean-up도 동일하게 작동합니다.
'(구)React 공식문서 > HOOK' 카테고리의 다른 글
Effect Hook 사용하기 (0) | 2023.03.05 |
---|---|
Hook API 참고서 (0) | 2023.03.05 |
Hook의 개요 (0) | 2023.03.05 |
Hook API 참고서 (0) | 2023.02.16 |
Hook의 개요 (0) | 2023.02.16 |