티스토리 뷰

JavaScript & TypeScript

React - LifeCycle API

kingsubin 2020. 11. 24. 09:23

https://twitter.com/dan_abramov/status/981712092611989509

 

컴포넌트 초기 생성

 

constructor

constructor(props) {
  super(props);
}

: 컴포넌트가 새로 만들어질 때마다 호출된다.

 

 

componentDidMount

componentDidMount() {
  // 외부 라이브러리 연동 : D3, masonry, etc
  // 컴포넌트에서 필요한 데이터 요청 : Ajax, GraphQL, etc
  // DOM 에 관련된 작업: 스크롤 설정, 크기 읽어오기 등
}

: 컴포넌트가 화면에 나타나게 됐을 때 호출된다.

 

 

 


컴포넌트 업데이트

 

static getDerivedStateFromProps

static getDerivedStateFromProps(nextProps, prevState) {
  // setState 를 하는 것이 아니라
  // 특정 props가 바뀔 때 설정하고 싶은 state 값을 리턴하는 형태로 사용
  
  /*
   if (nextProps.value !== prevState.value) {
     return { value: nextProps.value };
   }
   return null;
  */
}

: props 로 받아온 값을 state 로 동기화 하는 작업을 해줘야 하는 경우에 사용한다.

 

 

shouldComponentUpdate

shouldComponentUpdate(nextProps, nextState) {
  // return false 하면 업데이트 안함
  // return this.props.checked !== nextProps.checked
  return true;
}

: 컴포넌트를 최적화 하는 작업에서 매우 유용하게 사용된다.

기본적으로 true 를 반환, 따로 조건에 따라 false 를 반환하면 해당 조건에는 render 함수 호출하지 않는다.

 

 

getSnapshotBeforeUpdate

이 API 가 발생하는 시점

1. render()

2. getSnapShotBeforeUpdate()

3. 실제 DOM 에 변화 발생

4. componentDidUpdate

 

: 이 API 를 통해서, DOM 변화가 일어나기 직전의 DOM 상태를 가져오고, 여기서 리턴하는 값은

componentDidUpdate 에서 3번째 파라미터로 받아올 수 있게 된다.

 

getSnapshotBeforeUpdate(prevProps, prevState) {
  // DOM 업데이트가 일어나기 직전의 시점
  // 새 데이터가 상단에 추가되어도 스크롤바 유지하기
  // scrollHeight 는 전 후 를 비교해서 스크롤 위치를 설정하기 위함
  // scrollTop 은, 이 기능이 크롬에 이미 구현되어있는데,
  // 이미 구현이 되어있다면 처리하지 않기 위함
  
  if (prevState.array !== this.state.array) {
    const {
      scrollTop, scrollHeight
    } = this.list;
    
    // 여기서 반환하는 값은 componentDidMOunt 에서 snapshot 값으로 받아올 수 있음
    return {
      scrollTop, scrollHeight
    };
  }
}

componentDidUpdate(prevProps, prevState, snapshot) {
  if (snapshot) {
    const { scrollTop } = this.list;
    if (scrollTop !== snapshot.scrollTop) return; // 이미 구현되어있다면 처리하지않음
    const diff = this.list.scrollHeight - snapshot.scrollHeight;
    this.list.scrollTop += diff;
  }
}

 

 

componentDidUpdate

componentDidUpdate(prevProps, prevState, snapshot) {

}

: render()를 호출하고 난 다음에 발생하게 된다.

 

 

 


컴포넌트 제거

 

componentWillUnmount

componentWillUnmount() {
  // 이벤트, setTimeout, 외부 라이브러리 인스턴스 제거
}

: 주로 등록했었던 이벤트 제거, setTimeout 을 걸은것이 있다면 clearTimeout을 통하여 제거

추가적으로, 외부 라이브러리를 사용한게 있고 해당 라이브러리에 dispose 기능이 있다면 여기서 호출

 

 

 


컴포넌트에 에러 발생

 

componentDidCatch

componentDidCatch(error, info) {
  this.setState({
    error: true
  });
}

: 에러가 발생하면 이런식으로 componentDidCatch 가 실행되게 하고, state.error 를 trur로 설정하게 하고,

render 함수쪽에서 이에 따라 에러를 띄어주면 된다.

 

컴포넌트 자신의 render 함수에서 에러가 발생하는것은 잡아낼 수 없지만,

그 대신에 컴포넌트의 자식 컴포넌트 내부에서 발생하는 에러들을 잡아낼 수 있다.

 

보통, 렌더링 부분에서 오류가 발생하는것은 사전에 방지해주어야 한다. 

 

주로 자주 에러가 발생하는 이유 

1. 존재하지 않는 함수를 호출하려고 할때 (ex. props 로 받았을줄 알았떤 함수가 전달되지 않았을때)

this.props.onClick();

 

2. 배열이나 객체가 올 줄 알았는데, 해당 객체나 배열이 존재하지 않을때

this.props.object.value; // object is undefined
this.props.array.length; // array is undefined

 

-> render 함수에서 다음과 같은 형식으로 막아 줄 수 있다

render() {
  if (!this.props.object || !this.props.array || this.props.array.length ===0) return null;
  // object 나 array 를 사용하는 코드
}

 

-> 컴포넌트의 기본값을 설정하는 defaultProps 를 통해서 설정 가능

class Sample extends Component {
  static defaultProps = {
    onIncrement: () => console.warn('onIncrement is not defined'),
    object: {},
    array: []
  }
}

 

 

 

 


※ 출처

react-anyone.vlpt.us/05.html

'JavaScript & TypeScript' 카테고리의 다른 글

react-router-dom  (0) 2020.12.13
create-react-app :: NPM, NPX  (0) 2020.12.13
React - 시작하기  (0) 2020.11.23
11. Promise  (0) 2020.11.15
10. Callback  (0) 2020.11.15