📖컴포넌트가 렌더링 될 때 특정 작업(side effect)을 실행할 수 있는 Hook 중 하나
위에서 설명한 특정 작업(side effecs)
은 컴포넌트가 렌더링 된 이후 비동기
로 처리되어야 하는 부수적인 효과
들을 뜻한다. 이러한 기능으로 인해 함수형 컴포넌트
에서도 클래스형 컴포넌트
가 사용했던 생명주기 메서드
를 사용할 수 있게된다.
componentDidMount()
: 컴포넌트를 생성하고 첫 렌더링을 다 완료한 후 실행componentDidUpdate()
: 리-렌더링을 완료한 후 실행, 즉 render()가 업데이트 될 때마다 실행componentWillUnMount()
: 컴포넌트를 DOM에서 제거할 때 실행이러한 생명주기 메서드를 이제 함수형 컴포넌트에서도 useEffect()를 호출하여 사용이 가능하다는 것이다.
사용하는 이유는 개발자마다 다를 수 있다. 하지만 여태까지 리액트를 공부하다보면 하나의 컴포넌트 내에 복수의 state가 선언되어 사용될 수 있으며, 이러한 복수개의 state를 다룰 때 특정 state가 변경사항이 있다면 컴포넌트는 자동으로 리-렌더링
을 한다. 이러한 경우에 특정 효과를 막거나 또는 실행할 수 있는 유연성
을 부여할 수 있는 것이다. 또한, 생명주기 기준에서는 특정 시점에 해야만하는 행동이 있다면 useEffect를 통해 목표를 달성할 수 있을 것이다.
그렇다면 이제부터 useEffect를 사용해보자.
import React, {useEffect} from "react";
useEffect(function, deps);
// 첫번째 인자 : 실행하고자하는 함수, 두번째 인자 : 배열형태의 조건
위 코드를 보면 useEffect()에 두가지의 인자를 전달해준다. 첫번째 인자는 함수, 두번째 인자는 배열형태의 조건 객체이다. 여기서 deps라고 하는 것은 Dependencies를 가르킨다. 즉 인자로 전달된 state 등의 변경사항에 의존하여 첫번째 인자로 등록한 함수를 실행시킨다는 것이다.
두번째 인자값을 어떻게 주느냐에 따라 동작하는 모습을 코드로 알아보자.
useEffect(() => {
console.log("리-렌더링되면 계속 실행");
});
인자를 보게되면 첫번째 인자로 함수만 정의하였고, 두번째 인자는 비워둔 상태이다. 이런 경우 첫번째 인자로 전달된 함수는 리-렌더링되면 계속 실행하게 된다.
useEffect(() => {
console.log("한번만 실행");
}, []);
두번째 인자를 빈 배열로 넣어주면 첫 렌더링 시 딱 한번만 실행된다.
import {useState, useEffect} from "react";
function App(){
const [hi, setHi] = useState("hi");
useEffect(() => {
console.log("hi 값이 변경되면 실행");
}, [hi]);
return <h3>{hi}</h3>
}
두번째 인자로 컴포넌트 내 특정 state를 넣어주면 해당 state가 setter에 의하여 변경이 이루어진 경우에만 실행을 한다. 그렇다면 두번째 인자에 2개의 state값을 넣으려면? 당연히 [hi, hi2]
이런식으로 배열의 데이터를 넣는 것처럼 넣어주면된다. 아주 간편하다.
useEffect는 함수를 반환할 수 있는데 이 함수를 cleanUp이라고 한다.
useEffect(() => {
console.log("컴포넌트 생성");
return() => {
console.log("컴포넌트 삭제(cleanUp() 함수)");
}
});
이렇게 작성해주면 특정한 값이 업데이트 되기 직전에 cleanUp()을 실행 할 수 있다.
이렇게해서 이번 게시글에서는 리액트의 side effect를 실행할 수 있는 Hook인 useEffect에 대해서 알아보았다. 특정 시점에 특정한 동작을 하기 위해서는 클래스형 컴포넌트에서 생명주기 메서드를 통해 어느정도 효과를 볼 수 있었지만 useEffect를 사용하면 특정한 시점뿐만 아니라 특정 데이터가 변경되는 경우 등에 대해서도 컨트롤이 가능해지는 장점이 있다. props와 state의 변경사항을 포착하여 해당 데이터에 맞는 행동을 정의하는 것 만으로도 유연성이 높은 컴포넌트를 구성하는데 도움이 되는 것 같다는 생각이 든다.
사용하는데에 정해진 규칙은 있으나 규칙을 위반하지 않는 범위 내에서 창의적으로 사용한다면 굉장히 도움이 많이 될 것이다.
그럼 이만.👊🏽
useEffects => useEffect