React - state & Lifecycle

프최's log·2020년 10월 8일
0

React

목록 보기
3/5
post-thumbnail

state

 React에 대한 전반적인 포스팅 에서 간략하게 state 에 대해서 작성을 했는데, 이 포스팅에서 좀더 자세하게 다루려고 별도 포스팅으로 쪼갰다. 이전 포스팅에서 언급한 것들을 간단하게 가져오자면..

  • 내부에서 변할 수 있는 값
  • 비공개되어 컴포넌트에 의해 제어되는 값(로컬/캡슐화)

초기값 설정

React에서 state를 갖기 위해서는 'Class' 컴포넌트를 사용해야 한다.
초기값 설정 시, constructor 안에서 this.state = { }로 세팅을 할 수 있다. this를 생략한 state = { } 형태로도 작성할 수 있다. 함수형 컴포넌트에서 사용하고자 한다면, useState 훅을 이용해서 활용할 수 있다.

값 갱신(변경) - setState()

 state의 값을 변경할 때 setState를 사용하는데, 이에 앞서 주의사항이 존재한다.

직접 수정하지 않기

 값을 변경하는데 있어서 state의 값을 직접 수정하지 않아야 한다. 아래와 같은 형태로 사용하면 안 된다는 것이다.

// DO NOT USE - CASE1
this.state.count = this.state.count + 1
// DO NOT USE - CASE2
this.setState({
  count: this.state.count + 1
}); 

왜냐하면 React에서 리렌더링을 할 때, 이 변경을 감지 못해서 리렌더링을 하지 못하기 때문이다.

이전 state 값을 기준으로 값을 계산해야한다면, 객체 대신 updater 함수 를 전달해야한다.

// updater 함수의 형태
(state, props) => stateChange  

//state : 현 컴포넌트가 지니고 있는 state 상태(이전 상태)
//props : 새로운 객체를 만들기 위한 기반

// 사용할 수 없던 유형들에 대하 예제는
// 아래와 같이 수정해서 사용할 수 있다.
this.setState((prevState, props) => {
  return { count: prevState.count + 1 }
});

업데이트는 비동기적일 수 있다

 setState는 컴포넌트를 갱신하는데 있어 항상 즉각적으로 실행하는 것이 아닌 요청 을 하게 된다. 오히려 여러 변경사항과 함께 일괄 갱신을 하거나 나중으로 미루는 등 비동기적으로 행동할 수 있다.

업데이트 병합된다.

 setState를 이용하면 '필요한 부분'만 변화시킬 수 있는데, 이때 새로운 상태가 '추가'되는게 아니라 '덮어씌워진다'.

 우리는 왜 setState()를 왜 써야할까? 그 이유는 아래 설명하게 될 '생명주기(LifeCycle)'과 연관된다. React에서 값 변화는 생명주기에 의해 발생하기 때문에 setState()를 사용하게 된다.

공식문서 내용 참조


생명주기(LifeCycle)

컴포넌트 클래스에서 특별한 메서드를 선언하여 컴포넌트가 마운트되거나 언마운트 될 때 일부 코드를 작동할 수 있다. 이러한 메서드들을 'LifeCycle', 생명주기 메서드라고 불린다라고 공식문서에서 설명하고 있다.

쉽게 말하면, 컴포넌트가 생성이 되거나 화면에 등장(mount)하거나 새로운 상태를 가지는 것부터 화면에 사라지기 전(unmount)의 중요한 순간들이 있다. 이 순간들마다 렌더링되는데 이러한 순환상태를 생명주기라 한다.

이 생명주기에 대한 메소드들도 react 안에서 쓸 수 있다. 주로 쓰이는 메소드는 아래와 같다.

  • componentDidMount()
  • componentDidUpdate()
  • componentWillUnmount()

이를 시각적으로 볼 수 있는 react lifecycle methods diagram 을 통해, 흐름을 이해하고 외우도록 하자.

참조사이트
React의 생명 주기(Life Cycle)


state 끌어올리기

React에서 state를 공유하는 일은 그 값을 필요로 하는 컴포넌트 간의 가장 가까운 공통 조상으로 state를 끌어올림으로 이룰 수 있는데, 이를 state 끌어올리기 라고 부른다.

공식문서에서 섭씨화씨 변경에 대해서 차근히 설명을 하고 있는데 이를 따라하면 조금 이해가 쉽다.

  1. CalculatorTemperatureInput 컴포넌트를 2개 갖는다.
  2. TemperatureInput 을 통해 '섭씨'/'화씨' 온도를 받는다.
  3. 이 2개의 온도 값은 서로 동기화되어 화면에 출력된다.

input 의 값을 동기화 시키기 위해 TemperatureInput의 props를 최상위 부모인 Calculator 에게 state를 소유하도록 하면 해결된다. 그로 인해 Calculator 는 두 입력 필드의 현재 온도에 대한 “진리의 원천(source of truth)“이 된다고 설명하고 있다. 이 "진리의 원천"은 하나만 두어야 한다.

그림을 그리게 되면 Calculator 의 this.state가 TemperatureInput 로 내려감으로써 하나의 state에서 섭씨와 화씨온도 2개를 갖을 수 있게 된다. 즉, Input 에 섭씨온도를 적으면 화씨온도가 생기고, 화씨온도를 적으면 섭씨온도가 표시되는 동기화가 일어난다.

온도계산기 sandbox

사실 이 부분을 이해하기 위해 직접 코드를 짜보면서 어려움을 겪었는데, '바구니 내려주고, 올려받기'로 생각을 하니 코드 구현이 수월했다.

윗층에서 state에서 변경할 값 혹은 사용할 함수를 바구니에 담아 내려주고, 아랫층에서는 그 바구니에 윗층이 원하는 것(새로운 값 또는 함수 전달인자)을/를 담아 올려보낸다는 원리로 이해하고 사용했더니 구현하는데 어려움이 덜했다.


컴포넌트 트리

위의 그림에서처럼 CalculatorTemperatureInput 는 트리 구조를 가지고 있는데 이를 컴포넌트 트리라고 한다. state로부터 파생된 UI 또는 데이터는 오직 트리구조에서 자신의 아래, 하위 컴포넌트에만 영향을 미친다. 즉, React에서 데이터는 위에 아래(하향식,top-down), 단방향으로 흐르는 것이다.

트리구조가 props들의 폭포라고 상상하면 각 컴포넌트의 state는 임의의 점에서 만나지만 동시에 아래로 흐르는 부가적인 수원(water source)이라고 할 수 있다.

profile
차곡차곡 쌓아가는 나의 개발 기록

0개의 댓글