[React] 컴포넌트의 State 와 useState

Swimme·2021년 1월 17일
2

React

목록 보기
3/6

TIL 2021.01.17

State

  • state (상태) : 컴포넌트 내에서 동적으로 변경되는 값
  • props는 (함수 매개변수처럼) 컴포넌트에 전달되는 반면, state는 (함수 내 선언된 변수처럼) 컴포넌트 안에서 관리된다는 차이가 있다.

LifeCycle

  • 컴포넌트의 LifeCycle
    • 생성, 업데이트, 제거
    • 클래스형 컴포넌트는 생명주기 시점에 작동되는 함수를 지정할 수 있다. ( LifeCycle API )
    • 성능 이슈에 관련하여 공부할 필요성
  • LifeCycle API
    • 컴포넌트가 DOM 위에 생성되기 전 후 및 데이터가 변경되어 상태를 업데이트하기 전 후로 실행되는 메소드들
  • iOS view controller의 life cycle과 의미상 같다. 리액트가 화면을 업데이트하는 과정을 정확하게 이해하려면 공부할 필요가 있겠다.

Class형 컴포넌트

  • 리액트 함수형 컴포넌트 이전의 컴포넌트 사용 방식
  • 클래스형 컴포넌트는 state와 life cycle api를 직접 사용할 수 있다.
  • 함수형이 더 쉽고 재사용이 편리하여 클래스형은 이제 잘 사용하지 않지만 프로젝트의 유지보수를 위해 알고 있을 필요
class Item extends Component {
  ...
  
  // 별다른 함수 없이 state 초기값 설정
  this.state = { 
    name: string,
    count: number,
  }

  // state값 변경 : this.setState함수
  onClick = {()=>{
    this.setState({count: count+1}); 
  }}

  render() {
    return <div></div>
  }
}

React Hook

  • 함수형 컴포넌트에서 state와 Life Cycle의 feature들을 사용할 수 있게 해줌
  • useState, useEffect, useReducer, useContext

함수형 컴포넌트의 Hook을 이용하면 생명주기 메서드에 따라서가 아니라 코드가 무엇을 하는지에 따라 나눌 수가 있습니다


useState

  • 함수형 컴포넌트에 상태를 부여하는 함수
  • 상태 유지값 state와, state를 갱신해주는 Dispatcher로 구성
    • state에 직접 값을 할당하지 않고, Dispatcher setState함수가 state를 변경함
    • state가 변경될시 해당 컴포넌트가 재렌더링됨
  • 함수 컴포넌트의 state는 클래스와 달리 객체일 필요는 없고, 모든 타입이 될 수 있다.
  const [state, setState] = useState(initialState);

  setState(newState);
  setState(prevState => prevState+1);

State의 Immutability (불변성)

React에서 state는 불변성을 유지해야 한다.

  • state는 동적으로 변경되는 값이라면서 불변성을 유지해야 한다니, 의아할 수 있다.
    여기서 불변성은, 메모리 영역에서의 직접적인 변경이 불가능하다는 뜻이다. (재할당은 가능하다)
  • 기존 state의 불변성을 지켜주어야만, 리액트 컴포넌트에서 상태가 업데이트가 됐음을 감지 할 수 있고 이에 따라 필요한 리렌더링이 진행되기 때문이다.
  • js에서 기본적인 원시 타입은 모두 immutable type이지만, 객체나 배열은 참조 타입(Reference type)이기 때문에 기본적으로 변경이 가능한 타입이다.
  • 따라서 객체나 배열 타입의 state는 값이 업데이트 될 때 기존 객체나 배열의 참조 주소가 변경되지 않도록 주의가 필요하다.
  • es6부터는 배열 고차함수, spread operator, 또는 immutable.js 활용과 같은 immutable data pattern을 지원하기 시작했다.
  • 다음 예시는 고차함수 filter을 이용하여 기존 배열타입의 상태 불변성을 유지한 방법이다.
    // 기존 people 배열엔 영향 없이 새로운 배열을 생성
    const newPeople = people.filter((person) => {
      return person.id !== id;
    });

    setPeople(newPeople);

컴포넌트 업데이트 성능 최적화

React가 화면을 업데이트하는 과정
1. setState를 호출 (혹은 부모로부터 props를 전달 받음)
2. shouldComponentUpdate의 반환값이 true인 경우 render 호출
3. 가상 DOM과 실제 DOM을 비교해서 변경사항이 있으면 화면을 다시 그림

  • setState 함수는 LifeCycle API의 shouldComponentUpdate(nextProps, nextState)를 트리거하는데, 이 메소드의 boolean 반환값에 따라 render 호출 여부가 결정된다.
  • shouldComponentUpdate 는 기본값으로 true를 리턴하기 때문에, 이 메소드를 재정의하지 않으면 setState 호출마다 render가 호출되는 것이다.
  • 따라서 프로그램에 성능 이슈가 생겼을 때 문제가 되는 컴포넌트는shouldComponentUpdate를 구현해야 하는데, 이때 state의 불변성이 유지되지 않으면 내부 값들을 하나하나 확인해야 하기 때문에 로직이 복잡해진다.
profile
Life is Egg..🥚🐣🌟

0개의 댓글