Effect Hook 사용하기

Hooks는 리액트 16.8 버전에 새롭게 추가되었고 클래스를 사용하지 않고도 state나 다른 리액트 기능들을 사용할 수 있게 되었다.

 

Effect Hook은 함수 컴포넌트에서 side effect를 수행하도록 한다.

import React, {useState,useEffect} from 'react';

function Example(){
  const [count,setCount]=useState(0);
  
  //componentDidMount와 componentDidUpdate와 유사함
  useEffect(()=>{
    //브라우저 API를 사용하여 문서의 제목을 업데이트함
    document.title=`You clicked ${count} times`;
  });
  
  return(
    <div>
      <p>You clicked {count} times</p>
      <button onClick={()=>setCount(count+1)}>
        click me
      </button>
    </div>
  );
}

Tip.
리액트 클래스 생명주기 메소드에 친숙하다면, useEffect Hook을 componentDidMount,componentDidUpdate, 그리고 componentWillUnmount가 합쳐진 것이라고 생각하면 된다.

 

정리(Cleanup)를 하는 Effect

바로 전에 정리를 필요로 하지 않는 side effect의 구현 방법에 대해 살펴봤다. 하지만 몇몇의 effect는 정리를 하고.

예를 들어, 외부 데이터 소스에 대해 구독을 설정하고 싶을 때 사용한다. 이러한 경우, 메모리 낭비를 막기 위해서 정리를 하는 것은 매우 중요하고. 어떻게 구현하는지 클래스와 훅을 통해 비교하며 알아보자.

class FriendStatus extends React.Component{
  constructor(props){
    super(props);
    this.state={isOnlie: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';
  }
}

Hooks를 사용한 예시

Hooks를 사용하여 컴포넌트를 작성하는 방법을 알아보자.

정리를 하기 위해서 분리된 effect가 필요하다고 생각할 수 있다. 그러나 구독을 하거나 취소하는 코드는 결합도가 너무 높기 때문에 useEffect가 그 기능들을 함께 다루도록 구현되었다. effect가 함수를 반환한다면, 리액트는 정리할 타이밍에 그 함수를 작동시킬 것이다.

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 이후에 어떻게 정리할지 명시:
    return function cleanup(){
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id,handleStatusChange);
    };
  });
  
  if(isOnline===null){
    return 'Loading...';
  }
  return isOnline?'Online':'Offline';
}

참고
effect에서 이름이 있는 함수를 반환할 필요는 없다. 우리는 그 함수의 목적을 명확하게 하기 위해서 cleanup이라고 불렀지만, 화살표 함수나 혹은 다른 방법으로 호출하는 것도 가능하다.

'codestates' 카테고리의 다른 글

UI & UX  (0) 2022.06.27
mini Job-Searching  (0) 2022.06.22
URL & URI  (0) 2022.06.16
REST API  (0) 2022.06.15
React Props, State  (0) 2022.06.13