Note

React Lifecycle 본문

Dev/React

React Lifecycle

레모네모 2019. 12. 15. 22:50

1. 개요

리액트에서 클래스형 컴포넌트를 사용하면 라이프사이클 메소드를 사용할 수 있습니다.

(함수형 컴포넌트에서는 사용할 수 없습니다.)

라이프사이클 메소드는 컴포넌트가 mount 되거나 update, unmount 될 때 실행됩니다.

mount와 unmount는 이름으로 컴포넌트가 등록되거나 해제될 때라는 느낌이 오는데 update는 어떤 경우일까요?

리액트에서 update가 발생하는 경우는 아래와 같습니다.

  1. props 값이 변경될 때
  2. state 값이 변경될 때
  3. 부모 컴포넌트가 리렌더링될 때
  4. forceUpdate로 강제 업데이트를 트리거할 때

2. Mounting

리액트 컴포넌트는 마운트될 때 위와 같은 순서의 메소드를 실행하게 됩니다.

componentWillMount라는 메소드도 있지만 deprecated되어 사용하지 않기를 권장하고 있습니다.

메소드의 자세한 설명은 뒤에서 하도록 하겠습니다.

3. Updating

업데이트 메소드의 실행 순서는 위와 같고 자세한 설명은 뒤에서 하도록 하겠습니다.

componentWillUpdate, componentWillReceiveProps라는 메소드도 있지만 deprecated되어 사용하지 않기를 권장하고 있습니다.

4. Unmounting

언마운트될 때는 componentWillUnmount 메소드를 실행합니다.

자세한 설명은 뒤에서 하도록 하겠습니다.

5. Lifecycle References

render()

render() {
  ...
}

render 메소드는 Lifecycle 메소드 중 유일하게 필수 메소드로, 컴포넌트를 그리는 함수입니다.

메소드는 리액트 Element를 반환하고, 아무것도 그리고 싶지 않다면 null이나 false를 반환하면 됩니다.

이 안에서는 state에 변화를 주거나 브라우저 DOM에 접근해서는 안됩니다.

constructor()

constructor(props) {
  super(props);
  ...
}

constructor 메소드는 생성자 메소드로 여기에서 state를 초기화하거나 event 메소드를 binding할 수 있습니다.

리액트는 생성자에서 setState를 호출하거나 props의 값을 state에 복사하는것을 권장하지 않고 있습니다.

// 출처: https://reactjs.org/docs/react-component.html#constructor
constructor(props) {
  super(props);
  // Don't call this.setState() here!
  this.state = { counter: 0 };
  this.handleClick = this.handleClick.bind(this);
}
// 출처: https://reactjs.org/docs/react-component.html#constructor
constructor(props) {
 super(props);
 // Don't do this!
 this.state = { color: props.color };
}

componentDidMount()

componentDidMount() {
  ...
}

컴포넌트가 마운트되고 첫 렌더링을 마친 이후에 실행되는 메소드입니다.

다른 자바스크립트 라이브러리나 setTimeout, setInterval, 또는 네트워크 비동기요청 작업을 처리할 수 있습니다.

componentDidUpdate()

componentDidUpdate(prevProps, prevState, snapshot) {
  ...
}

컴포넌트가 업데이트되고 렌더링을 완료된 이후에 실행됩니다.

prevProps와 prevState를 통해 컴포넌트의 이전 속성이나 상태값에 접근할 수 있습니다.

또한 getSnapshotBeforeUpdate에서 반환한 값이 있다면 snapshot을 통해 값에 접근할 수 있습니다.

// 출처: https://reactjs.org/docs/react-component.html#componentdidmount
componentDidUpdate(prevProps) {
  // Typical usage (don't forget to compare props):
  if (this.props.userID !== prevProps.userID) {
    this.fetchData(this.props.userID);
  }
}

shouldComponentUpdate가 false를 반환한다면 실행되지 않습니다.

componentWillUnmount()

componentWillUnmount() {
  ...
}

컴포넌트가 DOM에서 마운트가 해제될 떄 실행됩니다.

componentDidMount에서 이벤트를 등록했다면 여기에서 이벤트를 해제해야 합니다.

여기서는 setState를 호출하더라도 절대 리렌더링이 발생하지 않기 때문에 setState를 호출하지 않아야 합니다.

shouldComponentUpdate()

shouldComponentUpdate(nextProps, nextState) {
  ...
}

props 또는 state 값이 변경됐을 때 리렌더링을 할 지 여부를 결정하는 메소드입니다.

이 메소드는 true 또는 false를 반환해야 하고 별도로 이 메소드를 명시하지 않으면 기본적으로 props나 state에 변화가 있을 때 true를 반환합니다.

static getDerivedStateFromProps()

static getDerivedStateFromProps(nexrProps, prevState) {
  ...
}

props의 값을 state로 옮기는 용도로 사용하는 함수입니다.

static 메소드로 this.state, this.props에 접근할 수 없습니다.

복사하는 state 값이 있다면 그 값을 객체로 반환하면 되고, 복사할 것이 없다면 null을 반환하면 됩니다.

static getDerivedStateFromProps(nexrProps, prevState) {
  if (nextProps.count !== prevState.count) {
    return {
      count: nextProps.count
    };
  }
  return null;
}

getSnapshotBeforeUpdate()

getSnapshotBeforeUpdate(prevProps, prevState) {
  ...
}

render에서 만들어진 요소가 DOM에 실제로 반영되기 직전에 호출되는 메소드입니다.

componentDidUpdate에서 업데이트 하기 직전의 값이 필요할 때 사용합니다.

snapshot(객체 혹은 값)을 반환하거나 null을 반환합니다.

6. Error Handling

static getDerivedStateFromError()

static getDerivedStateFromError(error) {
  ...
}

컴포넌트에 에러가 발생한 이후에 실행됩니다.

이 메소드에서 객체를 반환해서 state를 변경할 수 있습니다.

componentDidCatch()

componentDidCatch(error, info) {
  ...
}

컴포넌트에 에러가 발생했을 때 에러에 대한 상세한 정보를 기록할 때 사용합니다.

이곳에서 state를 변경하지 않고 getDerivedStateFromError에서 state를 변경할 것을 권장합니다.

 

// 출처: https://reactjs.org/docs/react-component.html#componentdidcatch
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    // Example "componentStack":
    //   in ComponentThatThrows (created by App)
    //   in ErrorBoundary (created by App)
    //   in div (created by App)
    //   in App
    logComponentStackToMyService(info.componentStack);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children; 
  }
}

 

'Dev > React' 카테고리의 다른 글

React Hook 소개  (0) 2020.02.17
React ref  (0) 2019.12.16
React Events  (0) 2019.12.15
React State  (0) 2019.12.15
React Prop  (0) 2019.12.08
Comments