본문 바로가기
FrontEnd/React.js

[React.JS] shouldComponentUpdate(), React.memo()

by Chaedie 2022. 8. 15.
728x90

공식 문서에서는? shouldComponenteUpdate(nextProps, nextState)

생활코딩 강의 중 shouldComponentUpdate() 가 나왔습니다.

생활 코딩 Class형 컴포넌트 리액트 강의 중 state의 배열을 array.push()를 통해 state를 변경 하는것이 불가능 하고, 새로운 배열을 만들어서 넣어야 한다고 했습니다. 여기서 한 걸음 더 나아가 추가 강의로 왜 그런지 찝찝한 분들을 위한 강의가 있었습니다.

그래서 그게 뭐임?

shouldComponentUpdate() 함수는 props, state가 새로운 값으로 갱신되어 렌더링이 발생되기 직전에 호출됩니다. 해당 함수에서 return false일 경우 렌더링이 일어나지 않고, return true가 될 경우 렌더링이 일어납니다. 그래서 기본값은 true입니다. (그래서 state와 props가 변경될 때마다 true가 반환되며 렌더링이 실행됩니다.)

해당 메서드는 성능 최적화만을 위한 것이라고 합니다. 이 메서드는 함수형 컴포넌트에서는 사용할 수 없어서 React.memo() 라는 방식을 통해 사용된다고 합니다.

엔트리 레벨인 저의 경우 사용할일이 아직 없지만, 앞으로 언젠간 이 함수를 만나게 될 날이 오겠죠? (공식문서나 레거시 프로젝트에서?) 그 때를 위해, 그리고 리액트의 기본 동작원리를 이해하기 위해 미리 조금씩 공부해두는것도 나쁘지 않다고 생각합니다. ㅎㅎ

강의에서 나온 코드

class TOC extends Component {
  shouldComponentUpdate(newProps, newState) {
      console.log('===> TOC Render shouldComponentupdate', newProps.data, this.props.data);
      if (this.props.data === newProps.data) {
        return false;
      }
      return true;
    }

  render() {
    ...
    }
}

위와 같이 sholudComponentUpdate()를 세팅해두면 새로운 프롭스와 기존의 프롭스가 다를때만 렌더링 되도록 만들수 있다고 합니다. 그래서 강제로 원본에 state를 세팅하는 형식보다 새로운 데이터를 만들어서 setState()를 하는 형식이 권장된다고 하네요.

저는 이 설명이 살짝 헷갈리는데요, 그 이유는 제가 배우고 있는 함수형 컴포넌트, useState Hook 에서는 setState라는 함수가 실행이 되면 이벤트핸들러가 끝나고 자동적으로 저렇게 이전값과 새로운값을 비교해서 그 둘의 값이 다른 값이면 setState가 진행되고, 리렌더링이 진행된다고 배웠습니다. 지금 좀 헷갈리니 setState를 사용했으나 데이터가 같을 때도 렌더링이 되는지 확인해보면 되겠죠???!!!

함수형 컴포넌트에서 setState 같은값 넣었을 때 리렌더링 되는지?

import { useState } from 'react';

function Main() {
  const [forPosting, setForPosting] = useState('noChange');
  const handleClick = () => {
    setForPosting(forPosting);
    console.log('set!!');
  };

  console.log('render, state :', forPosting);

  return <h1 onClick={handleClick}>{forPosting}</h1>;
}

export default Main;

위 코드와 결과를 보면 setState에 이니셜 밸류와 같은 값을 넣어서 실행시키면 실제로 리렌더링 되지 않는 것을 볼 수 있습니다.
똑같은 짓을 클래스형 컴포넌트에 넣어 보면 다르게 동작하려나요? 실험 고고


-   클래스형에서는 state의 값이 동일해도 그냥 리렌더링을 합니다.
-   함수형 (훅사용)에서는 state의 값이 동일하면 리렌더링 하지 않습니다. 그래서 걍 shouldComponentUpdate()를 Deprecate 시켰나봅니다 !!! ㅎㅎ

재밌네요

!!!!!!🚀🚀🚀
아래는 function, Class 코드가 같음을 보여주는 코드 블락!

import { useState } from 'react';

function Main() {
  const [forPosting, setForPosting] = useState('noChange');
  const handleClick = () => {
    setForPosting(forPosting);
    console.log('function set!!');
  };

  console.log('function render, state :', forPosting);

  return <h1 onClick={handleClick}>{forPosting}</h1>;
}

export default Main;
import React, { Component } from 'react';

class MainClass extends Component {
  constructor() {
    super();
    this.state = {
      forPosting: 'noChange',
    };
  }

  render() {
    console.log('Class render, state :', this.state.forPosting);
    return (
      <h1
        onClick={() => {
          this.setState({ forPosting: 'noChange' });
          console.log('Class set!!');
        }}
      >
        {this.state.forPosting}
      </h1>
    );
  }
}

export default MainClass;

내가 뭘 잘못했나 싶어서 setState에다가 this.state 넣어봤거든요? 그럼 똑같은거잖아요? 근데도 리렌더링 합니다.ㅋㅋㅋㅋ 클래스형컴포넌트는 골때렸었군요 🤣🤣

  render() {
    console.log('Class render, state :', this.state.forPosting);
    return (
      <h1
        onClick={() => {
          this.setState(this.state);
          console.log('Class set!!');
        }}
      >
        {this.state.forPosting}
      </h1>
    );
  }
}

댓글