[React] # 4 Life Cycle

simoniful·2021년 7월 6일
0

React

목록 보기
4/13
post-thumbnail

컴포넌트의 메서드

render, componentDidMount, componentDidUpdate, componentWillUnmount 등의 함수는 React.Component class에서 제공하는 메서드입니다. class 컴포넌트로 생성하면 위의 메서드를 이용할 수 있고, 컴포넌트의 lifecycle에 따라 각자의 메서드가 호출됩니다.

render()

클래스 컴포넌트에서 반드시 구현돼야하는 유일한 메서드. 호출되면 this.props와 this.state의 값을 활용하여 아래의 것 중 하나를 반환합니다. 컴포넌트의 state를 변경하지 않고, 호출될 때마다 동일한 결과를 반환해야하며, 브라우저와 직접적으로 상호작용을 하지 않습니다.

  • React 엘리먼트 : JSX 사용하여 생성
  • 문자열과 숫자
  • Boolean & null
  • Fragment : <>, </> - key attribute 전달 시 <React.Fragment key={item.id}>
  • Portal : 컴포넌트를 렌더링 시킬 때 랜더링 시킬 DOM을 선택하여 부모 컴포넌트의 바깥에서도 렌더링 할 수 있게 해주는 기능

Portal
리액트 v16 에서 도입된 기능, 이러한 기능을 써먹을 수 있는 가장 큰 예로는 'Modal'이나 'Popup' 이 있습니다.
👉🏻 Hooks를 이용한 Portal 사용법
👉🏻 Portal 기본서

constructor()

생성자는 보통 아래의 두 가지 목적을 위하여 사용됩니다:

  • this.state에 객체를 할당하여 지역 state를 초기화
  • 인스턴스에 이벤트 처리 메서드를 바인딩
constructor(props) {
  super(props);
  this.state = { counter: 0 };
  this.handleClick = this.handleClick.bind(this);
}

메서드를 바인딩하거나 state를 초기화하는 작업이 없다면, 해당 class형 React 컴포넌트에는 생성자를 구현하지 않아도 됩니다. 상속한 컴포넌트의 생성자를 구현할 때에는 다른 구문에 앞서 super(props)를 호출하며, 내부에서 setState()를 호출하면 안 됩니다. 직접 할당하여 초기 값을 잡아줍니다.

state에 props를 복사하면 안 됩니다!

constructor(props) {
 super(props);
 this.state = { color: props.color };
 // 이렇게 하지 마세요!
}

componentDidMount()

컴포넌트가 마운트된 직후, 즉 트리에 삽입된 직후에 호출됩니다. 데이터 구독을 설정하기 좋은 위치입니다. 데이터 구독(정기적인 발생)이 이루어졌다면, componentWillUnmount()에서 구독 해제 작업을 반드시 수행 해야합니다.

  • DOM 노드가 있어야 하는 초기화 작업
  • 외부에서 데이터를 불러와야 한다면, 네트워크 요청을 보낼 적절한 위치
  • componentDidMount()에서 즉시 setState()를 호출하는 경우

componentDidUpdate()

componentDidUpdate()는 갱신이 일어난 직후에 호출됩니다. setState()를 즉시 호출할 수도 있지만, 조건문으로 감싸지 않으면 무한 반복이 발생합니다. 상위에서 내려온 prop을 그대로 state에 저장하는 것은 좋지 않으며, 그 대신 prop을 직접 사용하는 것이 좋습니다.

  • 컴포넌트가 갱신되었을 때 DOM을 조작
  • 이전과 현재의 props를 비교하여 네트워크 요청을 보내는 작업
componentDidUpdate(prevProps) {
  // 전형적인 사용 사례 (props 비교를 잊지 마세요)
  if (this.props.userID !== prevProps.userID) {
    this.fetchData(this.props.userID);
  }
}

componentWillUnmount()

컴포넌트가 마운트 해제되어 제거되기 직전에 호출됩니다. 이 메서드 내에서 타이머 제거, 네트워크 요청 취소, componentDidMount() 내에서 생성된 구독 해제 등 필요한 모든 정리 작업 시에 활용 됩니다.


예제 분석

1초마다 갱신되는 시계를 예시로 보았을 때 class형 컴포넌트와 Hooks를 사용하여 구성하여 보면 다음과 같이 나타난다. render 메서드는 초가 바뀔때마다 호출되어 내용을 변경해주어야 한다.

Clock 컴포넌트는 mounting 동안은 본인 컴포넌트 내에서 값이 업데이트 되어야 하므로, state 변경 값을 관리해야 하고 lifecycle 메서드가 필요하다.

프로그래밍을 할 때 사용하던 리소스가 더 이상 필요없다면 없애주는 과정이 항상 필요하다. 따라서 Clock 컴포넌트가 mounting 될 때 timer를 추가하고, 더 이상 화면에서 unmounting 되는 순간 timer를 삭제해주어야 한다.

Class형 컴포넌트

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }
  // 1초마다 tick 함수 호출, 생성한 timer는 this.timerID에 저장
  
  componentWillUnmount() {
    clearInterval(this.timerID);
  }
  // unmount 될 때 clearInterval 함수를 사용해서 아까 만들었던 timer를 삭제

  tick() {
    this.setState({
      date: new Date()
    });
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}</h2>
      </div>
    );
  }
}

함수형 컴포넌트

function Clock(props) {
  const [date, setDate] = React.useState(new Date())

  React.useEffect(() => {
    let timerID = setInterval(
      () => tick(),
      1000
    );
    return function cleanup () {
      clearInterval(timerID);
    }
  });

  function tick() {
    setDate(new Date());
  }

  return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {date.toLocaleTimeString()}</h2>
      </div>
    );
};


ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

setInterval(), setTimeout() 👉🏻 쉬고 싶은 개발자
자바스크립트로 주기적인 작업을 실행하기 위해서 setInterval과 setTimeout 메소드를 사용합니다.

  • setInterval : 일정한 시간 간격으로 작업을 수행하기 위해서 사용. clearInterval 함수를 사용하여 중지. 주의할 점은 일정한 시간 간격으로 실행되는 작업이 그 시간 간격보다 오래걸릴 경우 문제가 발생.
  • setTimeout : 일정한 시간 후에 작업을 한번 실행. 보통 재귀적 호출을 사용하여 작업을 반복. 기본적으로 setInterval 과는 달리 지정된 시간을 기다린 후 작업을 수행하고, 다시 일정한 시간을 기다린후 작업을 수행하는 방식. 지정된 시간 사이에 작업 시간이 추가 되는 것. clearTimeout() 을 사용해서 작업을 중지.
  • clearInterval(), clearTimeout()이 실행 중인 작업을 중지시키는 것은 아니며, 지정된 작업은 모두 실행되고 다음 작업 스케쥴이 중지 되는 것.
profile
소신있게 정진합니다.

0개의 댓글