본문 바로가기
fastcampus

[패스트캠퍼스 수강 후기] 프론트엔드 인강 100% 환급 챌린지 28회차 미션

by 새우하이 2020. 10. 4.

class 형 컴포넌트의 state와 setState

이번에는 counter 컴포넌트를 class 컴포넌트로 만들어본다.
counter.js 를 열어 주석 처리해 주거나 지운다.

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

class Counter extends Component{
    render(){
        return (
            <div>
                <h1>0</h1>
                <button>+1</button>
                <button>-1</button>
            </div>
        );
    }
}
export default Counter;

Component를 import 해주고 마찬가지로 render를 사용해서 return 해준다.
그리고 index.js를 열어 Counter를 불러와주고 렌더링 시켜본다.
물론 지금은 작동하지 않는다. 값이 바뀌게 하기 위해서는 state를 사용해야 하는데
그전에 component에서 custom method를 만들어 본다.
custom method는 class 내부에 함수를 만드는 것을 의미한다.

// Counter.js
class Counter extends Component{
    handleIncrease(){
        console.log('increase');
    }
    handleDecrease(){
        console.log('decrease');
    }

render는 컴포넌트 내부에 지니고있는 method인 것이다.
이렇게 handleIncrease와 handleDecrease 처럼 우리가 새롭게 정의한 함수를 button에 onClick에 적용시켜준다.

또 다른 방법은 costum method를 선언할 때 arrow function 문법을 사용하는 것이다.

// Counter.js
.
.
return (
    <div>
        <h1>0</h1>
        <button onClick={this.handleIncrease}>+1</button>
        <button onClick={this.handleDecrease}>-1</button>
    </div>
);
.
.

이제 우리가 추후 button을 눌렀을 때 상태를 업데이트 하기 위해서는 this.setState를 사용해야 하는데 문제가 하나 있다.
handleIncrease를 버튼에 연결했다. 그런데 handleIncrease에서 console.log(this); 를 실행시키면 컴포넌트 인스턴스 자기 자신을 가리켜야되는데 이 함수를 특정 이벤트에 연결시켜주는 순간 이 handle함수와 this의 연결이 사라져버린다.
이렇게 된 이유는 각 method를 button들에 이벤트를 등록하는 과정에서 각 method 와 컴포넌트 인스턴스의 관계가 끊겨버리기 때문이다.

이를 해결하기 위한 방법중 첫번째
컴포넌트의 생성자 함수인 constructor에서 함수를 미리 바인딩 해주는 것이다.
constructor는 props라는 파라미터를 가지고 그리고 작업을 하기전 super(props)를 해준다.

// Counter.js
class Counter extends Component{
    constructor(props){
        super(props);
        this.handleIncrease = this.handleIncrease.bind(this);
        this.handleDecrease = this.handleDecrease.bind(this);
    }

bind라는 작업을 하게되면 만약 함수에서 this를 가리키게되면 이 constructor에서 사용하는 this를 가리키게 하라는 의미를 담고 있다.

이제 상태를 관리하는 방법을 알아보자.

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

class Counter extends Component{
    constructor(props){
        super(props);
        this.state ={
            counter: 0
        };

    }
    handleIncrease = () => {
        this.setState({
            counter: this.state.counter + 1
        })
    }
    handleDecrease = () =>{
        this.setState({
            counter: this.state.counter - 1
        })
    }
    render(){
        return (
            <div>
                <h1>{this.state.counter}</h1>
                <button onClick={this.handleIncrease}>+1</button>
                <button onClick={this.handleDecrease}>-1</button>
            </div>
        );
    }
}
export default Counter;

this.state를 지정해주고 counter를 지정해준다.

state는 무조건 객체 형태여야한다.
함수형 컴포넌트에서 useState를 사용할 때에는 객체, 배열, 숫자가 될 수 있었지만 여기에선 객체로만 가능하다.

여기서 this.setState를 통해 update하고 싶은 값을 넣어주면 해당 값만 업데이트해 주고 나머지 값들은 건드리지 않게 된다.

setState에서도 함수형 업데이트를 할 수 있다.

this.setState(state =>({
    counter: state.counter + 1
}));

state를 파라미터로 가져와서 원하는 변화를 준 객체를 반환해 주면 된다.

    this.setState({
        counter: this.state.counter + 1
    }) ; 

이 방법과의 차이가 무엇일까?

위의 두 코드를 여러번 사용해보면 그 차이를 알 수 있다.

this.setState(state =>({
    counter: state.counter + 1
}));
this.setState(state =>({
    counter: state.counter + 1
}));

이 방법으로 실행시켜보면 +1이 두번실행되서 2씩 올라가게 된다.

하지만

    this.setState({
        counter: this.state.counter + 1
    }) ; 
        this.setState({
        counter: this.state.counter + 1
    }) ; 

이 방식은 +2씩 될 것 같지만 그렇지 않다.
이렇게 되는 이유는 setState를 한다고 해서 상태가 바로 바뀌는 것이 아니기 때문이다. setState는 단순히 상태를 바꾸는 함수가 아니라 상태로 바꿔달라고 요청하는 함수로 이해 해야한다. 성능적인 문제 때문에 리액트는 상태가 바로 업데이트 되지 않고, 비동기적으로 업데이트 되기 때문이다.
그래서 만약 이런 작업을 해야할 일이 있다면 함수형 업데이트를 사용해야 업데이트가 제대로 이뤄진다.

LifeCycle 메서드

한국어로 생명주기 메서드라고 부른다.
컴포넌트가 브라우저상에 나타나고 업데이트되고, 사라지게 될 때 호출 되는 메서드들이다. 추가적으로 컴포넌트에 에러가 났을 때 호출 되는 메서드도 LifeCycle 메서드의 일부이다.
이는 클래스형 컴포넌트에서 사용할 수 있다.

생성 될 때
컴포넌트가 화면에 안보여지고 있다가 보여질 때를 의미한다.
생성 될 때는 constructor가 먼저 실행된다.

그리고 getDrivedStateFromProps는 props로 받아온 것을 state에 넣어야 할 때 이 메서드를 사용한다.

render 클래스 형태로 만든 컴포넌트에서 뭘 보여 줄 것인지.

React DOM 및 refs 업데이트 브라우저에 나타날 때
그다음 componentDidMount 가 발생한다. 이 시점에 브라우저에 우리가 원하는 형태가 보여지고 있다.

업데이트 할 때
컴포넌트가 리렌더링 될 때를 의미한다. 자신의 상태나 부모컴포넌트 리렌더링 될 때, 이 때 getDrivedStateFromProps는 마찬가지로 props로 받아온 것을 state로 넣어 줘야할 때 사용

shouldComponentUpdate는 컴포넌트를 최적화 해야하는 단계에서 사용한다. 컴포넌트에서 리렌더링이 불 필요한 시점에서 리렌더링을 막아 줄 수 있다. true를 반환하면 render가 호출 되고 아니면 false를 반환하면 멈춰서 렌더가 이뤄지지 않는다.
true가 반환되면 render 되고 getSnapshotBeforeUpdate 가 호출 된다. 이것은 브라우저에 변화를 일으키기 바로 직전에 사용된다. 그리고 마지막으로
componentDidupdate가 호출된다.

제거 할 때에는
componentWillUnmount 가 호출 된다. 주로 componentDidMount에서 이벤트를 등록했을때 그것들을 지워주는 작업들을 지워주는 작업을 한다.

마운트

  • constructor
    constructor 생성자 함수는 컴포넌트가 가장 처음 만들어질 때 호출되는 함수.
    super(props);를 해주는데 원래 react component라는 class가 지니고 있는 constructor 가 있는데 그 constructor를 덮어 씌우는 것인데 먼저 리액트가 지닌 constructor를 한번 호출해 주고 나서 덮어 씌우는것 때문에 super를 사용한다.
  • getDerivedStateFromProps
    여기서는 두가지 파라미터로 nextProps, prevState를 받아온다. 만약 현재 지니고 있는 props랑 state 내의 어떤 값이랑 다를 때, 어떤 객체를 return 하게 된다면 해당 값을 현재 상태에 반영시켜 준다. props로 받아온 어떤 값을 state에 동기화시켜주는 역할을 한다.
  • render
    render는 위의 두개가 호출 되고 render된 다음 모든 작업을 마치고 나서 모든 작업을 마치고 난 다음 브라우저에 컴포넌트가 보여졋을 때 아래가 실행된다.
  • componentDidMount
    이 메서드가 호출되는 시점에서는 컴포넌트에 있는 엘리먼트들이 브라우저에 나타난 상태여서 DOM에 직접 접근할 수 있다.

업데이트

  • getDerivedStateFromProps
    컴포넌트가 마운드 될 때, 업데이트 될 때 호출되고 props로 받아온 값을 state로 넣어주고 싶을 때 사용
  • shouldComponentUpdate
    만약 이 메서드에서 false를 반환하면 리렌더링을 하지 않고 true를 반환하면 리렌더링을 한다. 만약 이 메서드를 따로 구현하지 않으면 무조건 리렌더링 하게 된다.
  • render
  • getSnapshotBeforeUpdate
    shouldComponentUpdate 에서 true를 반환하면 render를 하고 이 함수가 호출된다. 컴포넌트가 리렌더링 되고 나서 브라우저에 변화를 반영시키기 바로 직전에 DOM에 접근할 수 있다. 그리고 여기서 어떤 값을 return 하게 되면 componentDidUpdate에서 조회할 수 있다.
  • componentDidUpdate
    prevProps와 this.props를 비교할 수 있다.

언마운트

  • componentWillUnmount
    컴포넌트가 사라지기 바로 직전에 호출되는 메서드
    주로 등록된 이벤트를 제거하거나 setTimeout을 취소하는 것

 

 

해당 내용은 아래 링크에서 수강할 수 있다.

프론트엔드 개발 올인원 패키지 with React Online. 👉https://bit.ly/2ETLEzm

 

프론트엔드 개발 올인원 패키지 with React Online. | 패스트캠퍼스

성인 교육 서비스 기업, 패스트캠퍼스는 개인과 조직의 실질적인 '업(業)'의 성장을 돕고자 모든 종류의 교육 콘텐츠 서비스를 제공하는 대한민국 No. 1 교육 서비스 회사입니다.

www.fastcampus.co.kr

 

댓글