UseEffect

김민지·2020년 8월 24일
0

Effect Hook을 사용하면 함수 컴포넌트에서 side effect를 수행할 수 있다.

리액트 컴포넌트에는 일반적으로 두 종류의 side effects가 있다. 정리(clean-up)각 필요한 것과 그렇지 않은 것. 이 둘을 어떻게 구분해야 할지 자세하게 알아보자.


정리(Clean-up)를 이용하지 않는 Effects

리액트가 DOM을 업데이트한 뒤 추가로 코드를 실행하야 하는 경우가 있다.
네트워크 리퀘스트, DOM 수동 조작, 로깅 등은 정리(clean-up)가 필요 없는 경우들이다. 이러한 예들은 실행 이후 신경 쓸 일이 없기 때문. class와 hook이 이러한 side effects를 어떻게 다르게 구현하는지 비교해보자.

Class를 사용하는 예시

리액트의 class 컴포넌트에서 render 메서드 그 자체는 side effect를 발생시키지 않는다. 이때는 아직 이른 시기로서 이러한 effect를 수행하는 것은 리액트가 DOM을 업데이트하고 난 이후이다.

리액트 class에서 side effect를 componentDidMount와 componentDidUpdate에 두는 것이 바로 이 때문이다.
예시로 돌아와서 리액트가 DOM을 바꾸고 난 뒤 문서 타이틀을 업데이트하는 리액트 counter 클래스 컴포넌트를 보자.

class Example extends React.Component {
  constructor(props) {
  super(props);
  this.state = {
     count:0
  };
}
conponentDidmount() {
 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.stae.count + 1 })}>
      Click me
      </button>
     </div>
    );
  }
}

위 코드에서 class 안의 두개의 생명주기 메서드에 같은 코드가 중복되는 것에 주의!

이는 컴포넌트가 이제 막 마운트된 단계인지 아니면 업데이트되는 것인지에 상관없이 같은 side effect를 수행해야 하기 때문이다. 개념적으로 렌더링 이후에는 항상 같은 코드가 수행되기를 바라는 것. 하지만 리액트 클래스 컴포넌트는 그러한 메서드를 가지고 있지 않다. 함수를 별개의 메서들 뽑아낸다고 해도 여전히 두 장소에서 함수를 불러내야 한다

이제 useEffect Hook에서 같은 기능을 어떻게 구현하는지 보자.

Hook을 이용하는 예시

아래의 코드는 위에서 이미 보았던 것이지만 이번에는 좀 자세히 보자.

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

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

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

return (

<div>
  <p>You clicked {count} times</p>
  <button onClick={() => setCount(count + 1)}>
    Click me
  </button>
</div>

);
}

useEffect가 하는 일은 무엇일까? useEffect Hook을 이용하여 우리는 리액트에게 컴포넌트가 렌더링 이후에 어떤 일을 수행해야하는 지를 말한다.리액트는 우리가 넘긴 함수를 기억했다가(이 함수를 effect라고 부른다)DOM 업데이트를 수행한 이후에 불러낼 것이다.

useEffect를 컴포넌트 안에서 불러내는 이유는? useEffect를 컴포넌트 내부에 둠으로써 effect를 통해 count state 변수(또는 그 어떤 prop에도)에 얻을 수 있다. 함수 범위 안에 존재하기 때문에 특별한 API 없이도 값을 얻을 수 있다. Hook 은 자바스크립트의 클로저를 이용하여 리액트에 한정된 API를 고안하는 것보다 자바스크립트가 이미 가지고 있는 방법을 이용하여 문제를 해결함.

useEffect는 렌더링 이후에 매번 수행되는걸까? 그렇다, 기본적으로 첫번째 렌더링과 이후의 모든 업데이트에서 수행된다.(나중에 effect를 필요에 맞게 수정하는 방법에 대해 다룰 것이다) 마운팅과 업데이트라는 방식으로 생각하는 대신 effect를 렌더링 이후에 발생하는 것으로 생각한는 것이 더 쉬울 것. 리액트는 effect가 수행되는 시점에 이미 DOM이 업데이트되었음을 보장한다.

profile
Welcome~!

0개의 댓글