React.js: useEffect Hook(2)

안녕하세요! 이전 포스팅에서 useEffect Hook의 기본적인 사용법에 대해 살펴보았고 마운트 되었을 때만 useEffect를 실행하고 싶을 때 함수의 두번째 파라미터로 배열을 추가해주면 된다는 사실을 알게되었습니다.

자 그러면 특정 값이 업데이트 될 때만 useEffect를 실행하고 싶을 때, 그리고 useEffect Hook의 뒷정리에 대한 개념을 살펴보도록 하겠습니다.

  1. 특정 값이 업데이트 될 때만 useEffect를 실행하고자 할 때
  2. 뒷정리란?

특정값이 업데이트 될 때만 useEffect를 실행하고자 할 때

클래스형 컴포넌트에서는 특정 값이 업데이트 될 때 다음과 같은 메서드를 사용했습니다.

componentDidUpdate(prevProps, prevState) {
  if (prevProps.value !== this.props.value) {
    doSomething();
  }
}

이것은 props 내부의 value 값이 업데이트 될 때만 doSomething이라는 특정 작업을 수행합니다.
그렇다면 함수형 컴포넌트에서 이러한 작업을 수행하려면 어떻게 해야 할까요?

이전 시간에 사용했던 코드를 가져와보겠습니다.

// Login.js

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

const Login = () => {
  const [id, setId] = useState('');
  const [pw, setPw] = useState('');
  
  useEffect(() => {
    console.log('Finished Rendering!');
    console.log({
      id,
      pw,
    })
  })
  
  const onChangeId = (e) => {
    setId(e.target.value);
  }
  const onChangePw = (e) => {
    setPw(e.target.value);
  }
  
  return (
    <div>
      <div>
        <input value={id} onChange={onChangeId} />
        <input value={pw} onChange={onChangePw} />
      </div>
      <div>
        <div>
          <b>ID: </b> {id}
        </div>
        <div>
          <b>PW: </b> {pw}
        </div>
      </div>
    </div>
  )
};

export default Login;

여기에서 useEffect를 다음과 같이 바꿔보면 어떻게 될까요?

useEffect(() => {
  console.log(id);
},[id]);

우리는 마운트 될 때만 useEffect Hook을 호출하고 싶을 때 함수의 두번째 파라미터로 배열을 추가해주면 된다는 사실을 알았고, 이 배열에 어떤 조건을 걸어주면 그 값이 업데이트 될 때만 useEffect Hook을 호출할 수 있습니다.

배열 안에 들어있는 값은 useState Hook으로 관리하고 있는 state를 넣어줄수도 있고, props로 전달받은 값을 넣어주어도 무방합니다.

뒷정리란?

useEffect는 렌더링 되고나서 그 직후에 계속 실행되며 두번째 파라미터에 넣는 내용에 따라 실행 조건이 달라지게 됩니다.
컴포넌트가 unmount 되기 전이나 update 되기 전에 어떠한 작업을 수행하도록 하고 싶으면 useEffect에서 cleanup 즉 뒷정리 함수를 반환해주어야 합니다.

Login.js의 useEffect부분을 다음과 같이 바꿔봅니다.

// Login.js의 useEffect

useEffect(() => {
  console.log('Effect');
  console.log(id);
  return () => {
    console.log('CleanUp');
    console.log(id);
  }
});

그 다음 App 컴포넌트를 다음과 같이 업데이트 해보세요

// App.js

import React, { useState } from 'react';
import Login from './Login';

const App = () => {
  const [activated, setActivated] = useState(false);
  return (
    <div>
      <button
        onClick={() => {
          setActivated(!activated)
        }}
      >
        {activated ? 'Unactivated' : 'Activated'}
      </button>
      {activated && <Login /> }
    </div>
  )
}

export default App;

자 그러면 우리가 작성한 컴포넌트를 실행해봅시다.

이렇게 버튼이 생긴 것을 확인할 수 있고, 버튼을 누르면

<input />에 값을 입력하면,

컴포넌트가 나타날 때 Effect가 나타나고 사라질 때 CleanUp이 반환됩니다.
그리고 렌더링 될 때마다 뒷정리 함수가 계속 발생합니다. 뒷정리 함수가 호출될 때는 업데이트 되기 이전의 값을 보여주고 있습니다.

마찬가지로 언마운트 될때만 뒷정리 함수를 호출하고 싶다면 useEffect 함수의 두번째 파라미터에 배열을 넣어주면 됩니다.

// Login.js의 useEffect

useEffect(() => {
  console.log('Effect');
  console.log(id);
  return () => {
    console.log('CleanUp');
    console.log(id);
  }
}, [name]);

어떠셨나요? useEffect 이제 제대로 활용할 수 있겠나요?

다음 포스팅은 또 다른 리액트 hook인 useReducer에 대해 다루도록 하겠습니다.

좋은 웹페이지 즐겨찾기