본문 바로가기
Front-End/React

[React Hook] 3. Effect Hook

by hongdor 2021. 2. 23.
728x90

출처 공식 문서 : Using the Effect Hook – React (reactjs.org)

 

 

1. Effect Hook

> componentDidMount와 componentDidUpdate, componentWillUnmount가 합쳐진 것
> 렌더링으로 완성된 DOM을 조작하는 것.

 

2. 예시

 

과거)

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

 

Hook)

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

 

 

3. useEffect가 하는일

> DOM이 업데이트 된 후 수행되는 함수이다.


4. useEffect를 컴포넌트 안에서 불러내는 이유

> state or props 변수에 접근할 수 있다.

 

5. 렌더링 이후 매번 수행되는가?

> 첫번째 렌더링 + 모든 업데이트마다 수행된다. 
  앞으로는 effect를 렌더링 이후에 발생하는 것으로 생각하는게 편하다.

 

6. useEffect의 이해

> 컴포넌트를 렌더링할 때 리액트는 우리가 이용한 effect를 기억하였다가 DOM을 업데이트한 이후에 실행합니다. 
이는 맨 첫 번째 렌더링은 물론 그 이후의 모든 렌더링에 똑같이 적용됩니다.

 

예시)

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });
}

 

 

7. DOM이 삭제될 때 실행되는 함수를 useEffect로 작성할 때

> return 문에 작성

 

아래 예시는 생성 시 ChatAPI.subscribe... 함수를 실행 / 컴포넌트가 사라질때 ChatAPI.unsubscribe... 실행

 

과거)

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() {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}

 

 

8. 팁

> 2개 이상의 useEffect를 사용할 수도 있다.

 

function FriendStatusWithCounter(props) {
  const [count, setCount] = useState(0);
  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  const [isOnline, setIsOnline] = useState(null);
  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });
  // ...
}
728x90

'Front-End > React' 카테고리의 다른 글

[React Hook] 5. 자신만의 Hook 만들기 (완)  (0) 2021.02.23
[React Hook] 4. Hook 규칙  (0) 2021.02.23
[React Hook] 2. State Hook  (0) 2021.02.22
[React Hook] 1. Hook 소개  (0) 2021.02.22
[react-redux] 5. 요약 (완)  (0) 2021.02.17

댓글