Study

리액트 기초 4일차 - LifeCycle API (2)

yujin2 2021. 2. 3. 19:35

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

constructor

컴포넌트가 가장 처음 만들어질 때 호출되는 함수

컴포넌트가 원래 가지고 있던 생성자 함수를 먼저 호출해주고 작업할 것

constructor(props) {
    super(props);
    console.log('constructor');
}

 

componentDidMount

외부 라이브러리 연동, 컴포넌트에서 필요한 데이터 요청, DOM에 관련된 작업을 할 때 호출

componentDidMount() {
    console.log('componentDidMount');
}

 

static getDerivedStateFromProps()

컴포넌트가 만들어지는 과정, 업데이트되는 과정에서 모두 사용 가능

setState를 하는 것이 아니라 특정 props가 바뀔 때 설정하고 싶은 state 값을 리턴하는 형태로 사용

static getDerivedStateFromProps(nextProps, prevState) {

}

nextProps는 다음으로 받아올 props값, prevState는 업데이트 되기 전의 상태를 가져오는 것

 

버튼을 누르면 props가 증가하고 그에 따라 state값도 증가하는 예제

App.js

import React, { Component } from 'react';
import MyComponent from './MyComponent';

class App extends Component {
  state = {
    counter: 1,
  }
  constructor(props) {
    super(props);
    console.log('constructor');
  }
  componentDidMount() {
    console.log('componentDidMount');
  }
  handleClick = () => {
    this.setState({
      counter: this.state.counter + 1
    });
  }
  render() {
    return (
      <div>
        <MyComponent value={this.state.counter}/>
        <button onClick={this.handleClick}>CLick Me</button>
      </div>
    );
  }
}

export default App;

MyComponent.js

import React, { Component } from 'react';

class MyComponent extends Component {
  state = {
    value: 0
  };

  static getDerivedStateFromProps(nextProps, prevState) {
    if (prevState.value !== nextProps.value) {
      return {
        value: nextProps.value
      };
    }
    return null;
  }
  render() {
    return (
      <div>
        <p>props: {this.props.value}</p>
        <p>state: {this.state.value}</p>
      </div>
    )
  }
}

export default MyComponent;

 

shouldComponentUpdate

특정 조건에 따라 렌더링을 막아줄 수 있는 함수

컴포넌트 업데이트 성능을 최적화할 수 있게 해줌

shouldComponentUpdate(nextProps, nextState) {

}

다음 받아올 props와 state 값을 파라미터로 가져옴

return false : 업데이트 안함

return true : 업데이트를 함 (디폴트값)

특정 로직에 따라 false 반환하게 하면 특정 상황에 최적화 해 줄 수 있음

 

MyComponent.js에 이 코드를 추가해주면,

shouldComponentUpdate(nextProps, nextState) {
    if (nextProps.value === 10) return false;
    return true;
}

props가 10이 되었을 때 렌더링하지 않아서 10이 출력되지 않음

 

getSnapshotBeforeUpdate()

컴포넌트가 업데이트 돼서 브라우저의 DOM에 반영되기 바로 직전에 호출되는 함수

업데이트 되기 바로 직전의 DOM 상태를 리턴시킨 값을 componentDidUpdate에서 받아올 수 있음

getSnapshotBeforeUpdate(prevProps, prevState) {

}

이전 props와 이전 state에 대한 값을 확인할 수 있음

 

- 보고 있는 화면에서 업데이트가 되어도 스크롤 위치가 유지될 수 있게 하는 예제

getSnapshotBeforeUpdate(prevProps, prevState) {
	if (prevState !== this.state.array) {
    	const {
        	scrollTop, scrollHeight
        } = this.list;
    }
    
    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;
    }
}

현재 상태와 이전의 상태가 다를 때 현재 리스트의 scrollTop, scrollHeight 값을 읽어와서 리턴 처리해서 componentDidUpdate의 3번째 파라미터로 받아와 원하는 작업 처리할 수 있음

 

componentDidUpdate

컴포넌트가 실제 업데이트 되고 난 다음에 호출되는 함수

componentDidUpdate(prevProps, prevState, snapshot) {

}

업데이트 되기 전의 props, state 값을 확인하고 현재 값과비교해서 특정 props가 바뀌면 어떠한 작업을 하게끔 해줄 수 있음

 

MyComponent.js에 이 코드를 추가해주면,

componentDidUpdate(prevProps, prevState) {
    if (this.props.value !== prevProps.value) {
      console.log('value값이 바뀌었다!', this.props.value);
    }
}

버튼을 클릭하여 props 값이 변할 때마다 콘솔창에 바뀐 value값이 뜨게 됨

 

componentWillUnmount

컴포넌트가 사라질 때 호출

 

App.js에서 counter값이 10보다 작을 때만 보여지게 코드를 수정한 후,

render() {
    return (
      <div>
        { this.state.counter < 10 && <MyComponent value={this.state.counter}/> }
        <button onClick={this.handleClick}>CLick Me</button>
      </div>
    );
}

MyComponent.js에 다음과 같은 코드를 추가해주면,

componentWillUnmount() {
    console.log('Good Bye');
}

counter 값이 10 이상이 되면 이 함수가 호출된다.

 

componentDidCatch

컴포넌트에 에러가 발생할 때 사용

에러가 발생할 수 있는 컴포넌트의 부모 컴포넌트에서 사용해야 함

componentDidCatch(error, info) {
    console.log(error);
    console.log(info);
}

error는 어떤 error가 발생했는지, info는 error가 어디서 발생했는지 알려주게 됨

이 정보를 네트워크 통해 특정 서버에 전달해준다거나 에러 발생을 보여줄 때 사용

실수로 잡지 못했던 에러들을 개발자가 알아낼 수 있음

 

state 객체에 error: false를 추가해주고, 에러 발생 시 true로 바뀌게 다음과 같은 코드를 넣어준 뒤,

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

render() 안에 error가 true 일 때 에러가 발생했다고 출력하는 코드를 넣어주면 사용자는 에러가 발생함을 알게 됨

if (this.state.error) {
      return (
        <div>
          에러 발생
        </div>
      )
  }

 

 

 

'Study' 카테고리의 다른 글

리액트 기초 3일차 - LifeCycle API  (0) 2021.02.02
리액트 기초 3일차 - Props와 State  (0) 2021.02.02
리액트 기초 2일차 - Webpack, Babel, JSX  (0) 2021.02.02