[React] 10 - Hooks : useEffect (2)

jungeundelilahLEE·2021년 2월 19일
1

React

목록 보기
16/24

goal

  • react hook useEffect 에 대해서 알아보자.

정리(clean-up)를 이용하는 ⭕️ Effects

  • 예를 들어, 외부 데이터에 구독(subscription)을 설정해야 하는 경우, 메모리 누수가 발생하지 않도록 정리(clean-up)하는 것은 매우 중요하다.

class component 사용

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';
  }
}

hook 이용

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() {
      // 지속적으로 작동하는 함수가 있다면,
      // useEffect() 내부에서,
      // cleanup() 함수로 정지시킬 수가 있다.
      // componentWillUnmount() 와 비슷한 동작을 기능을 수행한다.
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
    
  });

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}
  • effect에서 함수를 반환하는 이유는?

    • effect를 위한 추가적인 정리(clean-up) 메커니즘이다.
    • 모든 effect는 clean-up을 위한 함수를 반환할 수 있다.
    • 위 예제에서는 subscription의 추가&제거가 하나의 effect를 구성하고 있다.
  • 리액트가 effect를 clean-up 하는 시점은 정확히 언제일까?

    • 컴포넌트가 mount 해제되는 시점에 clean-up을 실행한다.
    • but, 위 예제처럼 effect는 한번이 아니라, 렌더링이 실행되는 때마다 실행된다.
    • 리액트가 다음 차례의 effect를 실행하기 전에, 이전 렌더링에서 파생된 effect도 함께 정리하는 이유가 여기에 있다.

function Foo () {
  
  const [count, setCount] = useState(0)
  
  useEffect( () => {
    document.title = `${count} times`
  }, [count] )
  // count가 변경될 때에만 필요하면 매번 갱신할 때마다 새로 생성할 필요는 없다.
  // 이러한 기능을 수행하기 위해, useEffect에 "두번째 인자"를 전달한다.
  // 이 두번째 인자는 effect가 종속되어 있는 값의 "배열" 이다.
  // 위의 코드는 "count가 변경될 때"만 title을 바꾸는 작업을 한다.
  // 만일, 두번째 인자로 빈 배열을 넣으면, (componentDidMount처럼) mount되는 시점에 1회만 작동한다.
  
}
  • useEffect는 컴포넌트의 렌더링 이후에 다양한 Side effect를 표현할 수 있다.
    • effect에 clean-up이 필요⭕️한 경우, 함수를 반환한다.
    • effect에 clean-up이 필요하지 않은❌️ 경우, 어떤 것도 반환하지 않는다.
  • 이처럼, effect HOOK는 위의 두 가지의 경우를 한 개의 API로 통합한다.
profile
delilah's journey

1개의 댓글

comment-user-thumbnail
2022년 1월 25일

react clean-up에 대해 궁금함이 있었는데 마침 딱 찾던 정보입니다! 잘 읽고 갑니다.!
적어주신 내용 참고해서 저도 포스팅에 사용해도 될까요?

답글 달기