State와 생명주기 - 주요 개념

hongregii·2023년 2월 25일
0

version issue

v16.8 부터 리액트는 함수형과 hooks라는 큰 변화를 맞이했다.
그래도 공식 문서의 이번 장은 주로 클래스 컴포넌트로 설명돼 있었는데,
새로운 공식문서(베타)는 useState()라는 Hook으로 설명한다. 함수형 + hook으로 본격적으로 바꾸고, 클래스형은 슬슬 버려지는 듯 하다.

본 페이지에서는 this.state를 설명하긴 하되, useState() 훅 위주로 정리하겠다.

v18.2 문서에 따르면...

클래스 컴포넌트는 state를 컴포넌트 클래스의 하나의 메소드로 본다. 정의된 클래스에서 private하게 완전히 제어된다고 한다. (그래서 전역상태관리 라이브러리를 사용하기도 함)

  1. constructor 부분에 state를 추가함 <- state라는 객체에 새로운 값을 push 하는 개념
  2. component Class의 componentDidMount() 메서드에 렌더링 된 후 실행될 함수를 설정 -> 여기에 setState() 함수 넣음.
  3. component Class의 componentWillUnmount() 메서드에 컴포넌트가 DOM에서 내려올때 (없어질때) 실행될 함수를 설정.

component의 생명주기를 설명하기 위해 적어봤다. 실제로 이렇게 state를 쓰는 개발자는 없을것이다.

State 알아야 할 세가지

1. 직접 State를 수정하지 말 것.

작동을 안한다. setState() 함수를 사용하지 않으면 다시 렌더링을 안함!

2. State 업데이트는 비동기

리액트의 정신 = 빠른 반응, 프런트에서 성능 향상. 누르면 앱처럼 제깍제깍 작동해야 함.
그리고 render 되기 전에 실행되어야 하기 때문이라고 한다.
그래서 비동기로 만들어놨음. 장점이 많지만, 이것 때문에 자칫하면 고생할 수 있다.

3. State 업데이트는 병합(Merge)됨.

클래스 컴포넌트의 state는 하나의 큰 객체.
여러개의 state를 선언했는데 하나만 setState() 로 업데이트 했다면, 하나만 바뀐 state 객체가 덮어씌워진다. (마치 git의 merge와 비슷한 과정). 바뀌지 않은 state 값을 그대로 두는 것은 병합이 shallow 하기 때문이라고 한다.

잘못된 예시 1 setState() 후 state를 바로 호출하는 경우
setState()가 비동기라서 겪는 가장 대표적 사례일 것이다.

// 잘못된 코드 예시
this.setState({ count: this.state.count + 1 });
console.log(this.state.count); // <- setState() 후 바로 호출.

비동기라서 setState()는 잠시 기다리고 (이벤트 루프 행), console.log() 가 먼저 실행된다.

잘못된 예시 2 setState() 연속기

<button onClick={()=>{
  setCount(count+1);
  if ( count < 3 ) {
    setAge(age+1);
  }         
}}>누르면한살먹기</button>

setCount()는 비동기 이기 때문에 if 문이 실행되는 시점이랑 개발자가 원하는 count값의 변동 시점이 안맞는다.

이를 어찌 해결한다? updater 함수를 인자로 집어넣는다 !

올바른 예시

setState((prev) => {prev + 1})
  • 리액트는 리렌더링까지 state를 업데이트하지 않음.
  • 리렌더링 시 여러개의 setState()를 배치로 실행하게 된다.
  • 그래서 prev 상태를 명시해주는 updater 함수를 사용해야 업데이트 시점이 더 명확해짐.

4. 하향식 / 단방향식 흐름

state는 private 하다. 다른 컴포넌트의 상태를 알 수 없다는 뜻.
그래서 다른 컴포넌트에서 state에 접근하고 싶다면, props로 전달해야 한다.
props는 부모에서 자식으로 전달된다고 했다. 즉 state는 부모에서 자식으로, props의 형태로만 가능한 것.
게다가 props에 들어있는 값을 꺼내 쓰는 것이기 때문에, 자식 컴포넌트는 그 값이 state인지, let인지, const인지 관심이 없다!

profile
잡식성 누렁이 개발자

0개의 댓글