useState, useEffect

dolphinSarah·2021년 1월 18일
0
post-thumbnail

useState〰️useEffect

함수형컴포넌트를 선호하는 이유

요즘은 많은 개발자들이 클래스형 컴포넌트보다 함수형 컴포넌트➕Hook을 사용한다.

클래스형 컴포넌트는 로직과 상태를 컴포넌트 내에서 구현하기 때문에 상대적으로 복잡한 UI 로직을 갖고 있는 반면, 함수형 컴포넌트는 state를 사용하지 않고 단순하게 데이터를 받아서(props) UI에 뿌려준다. Hook들을 필요한 곳에 사용하며 Logic의 재사용이 가능하다는 장점이 있어 함수형 컴포넌트➕Hook을 주로 사용한다고 한다.

오늘은 여러 Hook들 중 💙useState와 useEffect💙에 대해 알아보고자 한다.

useState

컴포넌트에서 동적인 값을 state라고 부른다. 이때, useState를 사용하여 컴포넌트에서 state를 관리할 수 있다.


useState를 사용할 때는 위처럼 state의 기본값을 파라미터로 넣어서 호출해준다. 이 함수를 호출하면 배열이 반환되는데, 여기서 첫번째(number)가 현재 상태, 두번째(setNumber)가 Setter 함수다.

Setter 함수는 파라미터로 전달받은 값을 최신 상태로 설정해준다.

다음은 클릭했을 때 숫자를 1 증가시켜주는 onIncrease 함수이다. 두 onIncrease 함수는 어떤 차이가 있는지 알아보자.

첫 번째 onIncrease는 업데이트 하고 싶은 새로운 값을 파라미터로 넣어주고 있는데, 두 번째 onIncrease는 기존 값을 어떻게 업데이트할지에 대한 함수를 파라미터로 넣어주고 있다.

즉, Setter 함수의 파라미터로 특정 값 뿐 아니라 기존 값의 업데이트에 대한 함수를 넣는다는 점도 꼭 기억하자.

useEffect

useEffect 훅은 함수형 컴포넌트에서 쓰이고 기존 클래스 컴포넌트의 라이프사이클 메서드를 대체한다. 먼저 라이프사이클 메서드에 대해 알아보자.

LifeCycle Method

라이프사이클(생명주기) 메서드는 크게 두 종류이다.

  • Will 메서드 : 어떤 작업이 실행되기 직전에 호출
  • Did 메서드 : 어떤 작업이 실행된 직후에 호출

생명주기 메서드에는 'Mount'라는 단어가 등장하는데, 'Mount'는 리액트가 컴포넌트를 실제 DOM에 삽입한다는 것이다. (리액트는 가상 DOM을 사용한다)

예를 들어, componentDidMount는 컴포넌트가 실제 DOM에 마운팅된 직후에 이 작업을 수행하겠다는 뜻이다.

그 다음, 클릭 이벤트 핸들러가 작동하여 state에 변화가 일어났다고 하자. 이때 리액트는 상태 변경을 감지하고, 가상 DOM을 실제 DOM에 동기화하는 업데이트 작업을 수행한다. 업데이트 직후에 어떤 작업을 수행하려면, componentDidUpdate 메서드를 사용하면 된다. (단, componentDidUpdate는 최초 렌더링 시에는 호출되지 않는다)

componentDidMount만 존재하면


버튼을 클릭하면 state의 count 값을 1 증가시키는 클래스 컴포넌트가 있고, componentDidMount 메서드가 있다. 이 메서드 내에는 도큐먼트 타이틀에 count 값을 표시하는 코드가 있다.

하지만 이 코드를 사용하게 되면, 버튼을 아무리 많이 클릭해도(count 값은 업데이트 되어도) 타이틀은 변하지 않는다.
그 이유는, componentDidMount는 최초 렌더링 시 한 번 호출된다. 그래서 this.state.count가 0일 때 딱 한 번 호출되고 끝이기 때문에 타이틀이 변하지 않는다.

componentDidUpdate만 존재하면


이번에는 같은 상황에서 componentDidUpdate만 존재하는 상황이다. 이 경우, 최초 렌더링 시 호출되지 않으므로 DOM에 리액트 요소들이 삽입되었을 때는 document 타이틀이 html에 설정된 타이틀 그대로 설정되어 있다.

이때, 버튼을 클릭하여 state를 변경하면 리액트가 이를 update하면서, 타이틀도 함께 업데이트된다.

useEffect

위에서 보았듯이, componentDidMount와 componentDidUpdate는 로직이 분리되어 있다. 그래서 최초 렌더링 시에도 count를 표시하고 싶고, state가 업데이트될 때도 count를 갱신하고 싶으면 다음과 같이 두 메서드를 모두 사용해야 한다.

코드를 보게 되면, 동일한 코드가 중복된다. 최초든, 업데이트 이후이든 렌더링 될 때마다 수행하고 싶은 작업이 있는데 기존의 라이프사이클 메서드를 사용하면 중복이 생기는 것이다.

useEffect는 이를 해결해준다.

useEffect를 사용하면 every render마다(리액트 컴포넌트가 렌더링될 때마다 특정 작업을 수행하도록 설정할 수 있는 Hook) 원하는 작업을 수행할 수 있기 때문에 코드를 중복할 필요가 없다.

useEffect를 사용하는 방법은, 위 코드처럼 내가 원하는 effect function을 패스해주면 된다. 여기서는 타이틀을 바꿔주었지만, 필수적인 API를 불러오거나 data를 fetch할 때 사용할 수도 있을 것이다.

마운트 될 때만 실행하고 싶다면

만약, useEffect에서 설정한 함수가, 컴포넌트가 화면에 제일 처음 렌더링될 때만 실행되고, 업데이트 할 때는 필요가 없는 경우에는 함수의 두번째 파라미터로 비어있는 배열을 넣어주면 된다.

위와 같이 코드를 작성했다면, 컴포넌트가 처음 나타날 때만 콘솔에 문구가 나타나고 이후에는 나타나지 않을 것이다.

특정 값이 업데이트 될 때만 실행하고 싶다면

useEffect를 사용할 때, 특정 값이 변경될 때만 호출하고 싶다면 useEffect의 두번째 파라미터로 전달되는 배열 안에 검사하고 싶은 값을 넘겨주면 된다.

뒷정리

useEffect는 기본적으로 렌더링 직후마다 실행되며, 두번째 파라미터 배열에 무엇을 넣느냐에 따라 실행 조건이 달라진다.

만약 컴포넌트가 언마운트되기 전이나 업데이트 되기 직전에 어떠한 작업을 수행하고 싶다면 useEffect에서 뒷정리(cleanup) 함수를 반환해줘야 한다.

컴포넌트가 나타날 때 콘솔에 effect가 보이고, 사라질 때 cleanup이 보이게 된다.

그리고 렌더링이 될때마다 cleanup 함수가 계속 보여지고, cleanup이 호출될 때는 업데이트 되기 직전의 값을 보여준다. 만약, 오직 언마운트될 때만 뒷정리 함수를 호출하고 싶다면 useEffect 함수의 두번째 파라미터에 비어있는 배열을 넣으면 된다.

profile
Exploring Front-end_.

0개의 댓글