상태 끌어올리기(Lifting State Up)와 Effect Hook

손연주·2021년 6월 28일
0
post-custom-banner

1. State 끌어올리기

1-1. 컴포넌트로 생각하기

우리가 기획자나 PM, 또는 UX 디자이너로부터 디자인을 전달받고 나면, 이를 컴포넌트 계층 구조로 나눠야 한다. 단일 책임 원칙에 따른 구분이며 하나의 컴포넌트는 한가지 일만 해야한다. 트위터 클론 코딩을 한다고 생각해보자.


  1. 트위터 전체를 보여주는 Twittler
  2. 새 트위터를 작성하는 곳 NewTweetForm
  3. 트윗 목록들 Tweets 이는
  4. 여러개의 SingleTweet으로 나뉜다

컴포넌트로만 생각했을 때, 상위 컴포넌트와 하위 컴포넌트로 나뉘어 트리 구조로 나타낼 수 있다.

1-2. 단방향 데이터 흐름(one-way data flow)

리액트는 데이터를 위에서 아래로 보내는 단방향 top-down 구조이다. 컴포넌트는 컴포넌트 바깥에서 props를 이용해 데이터를 마치 인자(arguments) 혹은 속성(attributes)처럼 전달받을 수 있다. 즉 데이터를 전달하는 주체는 부모 컴포넌트가 된다. 이는 데이터 흐름이 하향식(top-down)임을 의미한다.

상태를 어디에 위치시켜야 할까?
하나의 상태를 기반으로 여러개의 컴포넌트가 영향을 받는다면 이 때에는 공통 소유 컴포넌트, 즉 영향을 주고있는 부모 컴포넌트에 작성한다.

1-3. 상태 끌어올리기

리액트는 단방향 구조라는 것을 배웠다. 그런데, 데이터가 아래에서 위로 가는 경우도 발생한다. 위의 트위터에서 새로운 트윗 작성한다고 생각해보자. 단일 원칙에 의해 NewTweetForm 컴포넌트에서 작성할 수 있다. 새로운 트윗이 작성됐으면 Twittler와 Tweets가 바뀌어야 한다. 하위 컴포넌트에서 이루어지는 트윗 추가 버튼을 통한 이 액션은 부모의 상태를 변화시킨다는 것이다. Q) 그럼 역방향이 되어서 리액트 원칙에 어긋나지 않나요? A) 단방향 데이터 흐름에 부합하는 해결 방법은 바로 "State 끌어올리기(Lifting state up)" 이다.

상위 컴포넌트의 "상태를 변경하는 함수" 그 자체를 하위 컴포넌트로 전달하고(props), 이 함수를 하위 컴포넌트가 실행한다.

2. Effect Hook

2-1. Side Effect

  • side effect(부수 효과) : 함수 내에서 어떤 구현이 함수 외부에 영향을 끼치는 경우 해당 함수는 Side Effect가 있다고 말한다.
let foo = 'hello';

function bar() {
  foo = 'world';
}

bar(); // bar는 Side Effect를 발생시킵니다!
  • Pure Function (순수 함수) : 오직 함수의 입력만이 함수의 결과에 영향을 주는 함수. 입력으로 전달된 값을 수정하지 않는다.
function upper(str) {
  return str.toUpperCase(); // toUpperCase 메소드는 원본을 수정하지 않습니다 (Immutable)
}

upper('hello') // 'HELLO'

보통 React 애플리케이션을 작성할 때에는, AJAX브라우저가 가지고있는 XMLHttpRequest 객체를 이용해서 전체 페이지를 새로 고치지 않고도 페이지의 일부만을 위한 데이터를 로드하는 기법 요청이 필요하거나, LocalStorage 또는 타이머와 같은 React와 상관없는 API를 사용하는 경우가 발생할 수 있다. 이는 React의 입장에서는 전부 Side Effect 이다. React는 Side Effect를 다루기 위한 Hook인 Effect Hook을 제공한다.

2-2. Effect Hook

API
useEffect(함수, [종속성1, 종속성2, ...])
: 컴포넌트 내에서 Side effect를 실행할 수 있게 하는 Hook

  • 첫번째 인자 : 함수
  • 두번째 인자 : 우리가 관찰하고 싶은 값이 배열(어떤 값의 목록)로 들어간다. 배열 내의 어떤 값이 변할 때에만, (effect가 발생하는) 함수가 실행된다. Hook은 최상위 컴포넌트에서 쓰며 함수 내에서 호출한다.

effect hook의 발생

  • 컴포넌트 생성 후 처음 화면에 렌더링(표시)
  • 컴포넌트에 새로운 props가 전달되며 렌더링
  • 컴포넌트에 상태(state)가 바뀌며 렌더링

이와 같이 매 번 새롭게 컴포넌트가 렌더링될 때 Effect Hook이 발생한다

단 한번만 실행되는 Effect 함수

두번째 배열이 빈 배열[]이라면?

  1. 빈 배열 넣기
    useEffect(함수, [])

빈 배열을 useEffect의 두번째 인자로 사용하면, 이 때에는 컴포넌트가 처음 생성될때만 effect 함수가 실행된다. 처음 단 한번, 외부 API를 통해 리소스를 받아오고 더이상 API 호출이 필요하지 않을 때에 사용할 수 있다.

  1. 아무것도 넣지 않기 (기본 형태)
    useEffect(함수)

기본 형태의 useEffect는 컴포넌트가 처음 생성되거나, props가 업데이트되거나, 상태(state)가 업데이트될 때 effect 함수가 실행된다.

2-3. 컴포넌트 내에서 AJAX 요청

profile
할 수 있다는 생각이 정말 나를 할 수 있게 만들어준다.
post-custom-banner

0개의 댓글