๊ด€๋ฆฌ ๋ฉ”๋‰ด

Daehyunii's Dev-blog

classํ˜• ์ปดํฌ๋„ŒํŠธ - pureComponent ๋ณธ๋ฌธ

๐Ÿ“š Language & CS knowledge/React

classํ˜• ์ปดํฌ๋„ŒํŠธ - pureComponent

Daehyunii 2022. 12. 16. 13:33
PureComponent
shouldComponentUpdate๋ฅผ ๊ตฌํ˜„ํ•ด ๋†“์€ ์ปดํฌ๋„ŒํŠธ๋‹ค.

 

  pureComponent์˜ ์ฒซ ๋ฒˆ์งธ ๊ธฐ๋Šฅ์€ state์˜ ๋ณ€๊ฒฝ์ด ์žˆ๋Š” ๊ฒฝ์šฐ์— ์ž๋™์œผ๋กœ true, false๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด state์˜ ๋ณ€ํ™”๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋ฆฌ๋ Œ๋”๋ง ๋˜๋„๋ก ์ตœ์ ํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์ž.

import React, { Component } from "react";

class Test extends Component {
  state = {
    counter: 0,
  };

  onClick = () => {
    this.setState({});
  };

  render() {
    return (
      <div>
        <button onClick={this.onClick}>ํด๋ฆญ</button>
      </div>
    );
  }
}

export default Test;

 

  PureComponent๊ฐ€ ์•„๋‹Œ Component๋กœ ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒฝ์šฐ, React.Component๋Š” shouldComponentUpdate๋ฅผ ๋”ฐ๋กœ ์„ค์ •ํ•ด์ฃผ์ง€ ์•Š์€ ๊ฒฝ์šฐ, ํ•ญ์ƒ true๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ฆ‰, setState๊ฐ€ ์‹คํ–‰๋˜๋ฉด state, props์˜ ๋ณ€๊ฒฝ ์—ฌ๋ถ€๋ฅผ ์‹ ๊ฒฝ์“ฐ์ง€ ์•Š๊ณ  ๋ฌด์กฐ๊ฑด์ ์œผ๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—…๋ฐ์ดํŠธ์‹œํ‚จ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ๋ถˆํ”ผ์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง์ด ์ผ์–ด๋‚˜๊ฒŒ ๋œ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ shouldComponentUpdate()๋ฅผ ํ†ตํ•ด ์ง์ ‘ ์„ค์ •ํ•ด์ฃผ๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์ง€๋งŒ Component ๋Œ€์‹  PureComponent๋กœ ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค. ๋ฆฌ๋ Œ๋”๋ง์ด ๋˜๊ธฐ ์ „ ๊ธฐ์กด state์™€ ๋ฐ”๋€” state์˜ ๋ณ€๊ฒฝ์„ ํ™•์ธํ•˜์—ฌ ๋ณ€๊ฒฝ์ด ์žˆ๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋ Œ๋”๋ง๋˜๊ฒŒ ํ•œ๋‹ค. ๋‹ค์‹œ PureComponent๋กœ ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•ด ๋ณด์ž.

 

import React, { PureComponent } from "react";

class Test extends PureComponent {
  state = {
    counter: 0,
  };

  onClick = () => {
    this.setState({});
  };

  render() {
    return (
      <div>
        <button onClick={this.onClick}>ํด๋ฆญ</button>
      </div>
    );
  }
}

export default Test;

 

โš ๏ธ์ฃผ์˜์‚ฌํ•ญ

PureComponent๋กœ ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•œ ๊ฒฝ์šฐ์— ์˜ˆ์ƒํ•˜์ง€ ๋ชปํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. state์˜ ๋ณ€๊ฒฝ์„ ํ™•์ธํ•  ๋•Œ ์ฐธ์กฐ ์ „๋‹ฌ์ด ๋˜๋Š” ์ž๋ฃŒ๊ตฌ์กฐ์˜ ๊ฒฝ์šฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์ž.

 

import React, { PureComponent } from "react";

class Test extends PureComponent {
  state = {
    counter: 0,
    array: [],
  };

  onClick = () => {
    const array2 = this.state.array;
    array2.push(1);
    console.log(this.state);
    
    this.setState({
      array: array2,
    });
  };

  render() {
    return (
      <div>
        <button onClick={this.onClick}>ํด๋ฆญ</button>
      </div>
    );
  }
}

export default Test;

 

  ๋ฒ„ํŠผ ํด๋ฆญํ•˜๋ฉด array2์—๋Š” ์ˆซ์ž ๊ฐ’ 1์„ pushํ•˜๊ฒŒ ๋˜๊ณ  setState๋ฅผ ํ†ตํ•ด array์˜ ๊ฐ’์„ array2๋กœ ๋ณ€๊ฒฝํ•˜๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด state์˜ ์ •๋ณด๊ฐ€ ๋ฐ”๋€Œ๊ฒŒ ๋œ ๊ฒƒ ์•„๋‹Œ๊ฐ€?? ๋‹ค์Œ ์˜์ƒ์„ ์‚ดํŽด๋ณด์ž! 

 

 

 

  state์˜ ๋ณ€๊ฒฝ์ด ์žˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋ฆฌ๋ Œ๋”๋ง ๋˜๊ณ  ์žˆ์ง€ ์•Š์€ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. (๋ฆฌ๋ Œ๋”๋ง ๋˜๋Š” ๊ฒฝ์šฐ highlight์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ด ํ™”๋ฉด์— ๋ณด์—ฌ์ง€๊ฒŒ ๋˜๋Š” ๋ฆฌ์•กํŠธ ๊ฐœ๋ฐœ ๋„๊ตฌ์˜ ์˜ต์…˜์ด ์žˆ๋‹ค) ์ด๋Ÿฐ ๊ฒฝ์šฐ์—๋Š” ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์Œ์—๋„ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ ๋œ ๊ฒƒ์„ PureComponent๋Š” ์ธ์ง€ํ•˜์ง€ ๋ชปํ•˜๊ณ  ๋ฆฌ๋ Œ๋”๋ง ๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ฐธ์กฐ ์ „๋‹ฌ์˜ ๊ฒฝ์šฐ์—๋Š” ์ „๊ฐœ์—ฐ์‚ฐ์ž์™€ ๊ฐ™์€ ์–•์€ ๋ณต์‚ฌ๋ฅผ ํ†ตํ•ด ๊ธฐ์กด ๋ฐ์ดํ„ฐ์™€ ๋ณ€๊ฒฝ๋  ๋ฐ์ดํ„ฐ๋ฅผ ๋ฌถ์–ด ํ•˜๋‚˜์˜ ๋ฐ์ดํ„ฐ๋กœ ๋‹ค์‹œ ๋งŒ๋“ค์–ด ๊ฐ’์„ ๊ฐฑ์‹ ํ•ด์ฃผ์–ด์•ผ PureComponent๊ฐ€ state ๋ณ€๊ฒฝ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

 

import React, { PureComponent } from "react";

class Test extends PureComponent {

  state = {
    counter: 0,
    array: [],
  };


  onClick = () => {
    const array2 = this.state.array;
    array2.push(1);
    console.log(this.state);
    this.setState({
      array: [...this.state.array, array2],
    });
  };

  render() {
    return (
      <div>
        <button onClick={this.onClick}>ํด๋ฆญ</button>
      </div>
    );
  }
}

export default Test;

 

 

์–•์€ ๋ณต์‚ฌ๋ฅผ ํ†ตํ•ด์„œ array์˜ ๊ฐ’์„ ๊ฐฑ์‹ ํ•ด์ฃผ๋ฉด state์˜ ๋ณ€๊ฒฝ์„ ๊ฐ์ง€ํ•˜๊ณ  ๋ Œ๋”๋ง๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 

 

  pureComponent์˜ ๋‘ ๋ฒˆ์งธ ๊ธฐ๋Šฅ์€ props์˜ ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ํ•˜์—ฌ ๋ฆฌ๋ Œ๋”๋ง ๋˜๊ฒŒ ๋งŒ๋“ค์–ด ์ฃผ๋Š” ๊ธฐ๋Šฅ์ด ์žˆ๋‹ค. ํ•œ ๊ฐ€์ง€ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ์€ pureComponent๋Š” classํ˜• ์ปดํฌ๋„ŒํŠธ์—๋งŒ ์ ์šฉ์ด ๊ฐ€๋Šฅํ•œ๋ฐ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—๋„ ์ด์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ํ•ด์ฃผ๋Š” ๊ฒƒ์ด ์žˆ๋Š”๋ฐ ๊ทธ๊ฒƒ์ด ๋ฐ”๋กœ React.memo์ด๋‹ค. ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์ž. (์ด๋ฒˆ์—๋Š” ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ •๋ฆฌํ•ด๋ณด๊ฒ ๋‹ค)

 

 

//์ž์‹ ์ปดํฌ๋„ŒํŠธ
import React from "react";

const Try = (props) => {
  return (
    <li>
      <div>{props.value.try}</div>
      <div>{props.value.result}</div>
    </li>
  );
};
Try.displayName = "Try";
//๋‹จ, memo๋ฅผํ•˜๊ฒŒ ๋˜๋ฉด ์ปดํฌ๋„ŒํŠธ์˜ ์ด๋ฆ„์ด ๋ณ€๊ฒฝ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ปดํฌ๋„ŒํŠธ์˜ ์ด๋ฆ„์„ ์ œ๋Œ€๋กœ ๋ณ€๊ฒฝ์‹œ์ผœ์ฃผ์–ด์•ผ ํ•œ๋‹ค.
export default Try;

 

  ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ ์ฝ”๋“œ๊ฐ€ ๊ธธ์–ด ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ ์ฝ”๋“œ๋Š” ์ƒ๋žตํ•˜๋„๋ก ํ•˜๊ฒ ๋‹ค! ์œ„์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๋„˜๊ฒจ ๋ฐ›์•„ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ™œ์šฉํ•˜๊ฒŒ ๋œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ divํƒœ๊ทธ ๋‚ด์— ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋Š” ๊ณ„์† ๊ณ ์ •๋œ ๊ฐ’์ž„์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋˜๋ฉด Try ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋„ ๋‹ค์‹œ ๋ฆฌ๋ Œ๋”๋ง๋˜๊ฒŒ ๋œ๋‹ค. ์ด๋Š” ๋งค์šฐ ๋น„ํšจ์œจ์ ์ด๋‹ค.(์˜์ƒ์—์„œ๋Š” li์˜ props ๋ณ€๊ฒฝ์ด ์—†์Œ์—๋„ ๊ณ„์† ๋ฆฌ๋ Œ๋”๋ง ๋œ๋‹ค.) ๋‹ค์Œ ์˜์ƒ์„ ํ†ตํ•ด ํ™•์ธํ•ด ๋ณด์ž.

 

 

 

  ์ด๋Ÿฌํ•œ ๋น„ํšจ์œจ์ ์ธ ๋ฆฌ๋ Œ๋”๋ง์„ ๋ง‰๊ธฐ์œ„ํ•ด props๊ฐ€ ๋ณ€๊ฒฝํ•œ ๊ฒฝ์šฐ์—๋งŒ ๋ฆฌ๋ Œ๋”๋ง ๋˜๋„๋ก ๊ณ ์ฐจ ์ปดํฌ๋„ŒํŠธ์ธ React.memo๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.๋ฉ”๋ชจ๋กœ ๋ž˜ํ•‘ ๋  ๋•Œ, React๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ฉ”๋ชจ์ด์ง•ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‹ค์Œ ๋ Œ๋”๋ง์ด ์ผ์–ด๋‚  ๋•Œ props๊ฐ€ ๊ฐ™๋‹ค๋ฉด, React๋Š” ๋ฉ”๋ชจ์ด์ง•๋œ ๋‚ด์šฉ์„ ์žฌ์‚ฌ์šฉํ•œ๋‹ค. ๋‹ค์‹œ ์ ์šฉํ•ด ๋ณด์ž. 

 

โ˜‘๏ธ ๊ณ ์ฐจ ์ปดํฌ๋„ŒํŠธ(HOC, Higher Order Component)๋Š” ์ปดํฌ๋„ŒํŠธ ๋กœ์ง์„ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ React์˜ ๊ณ ๊ธ‰ ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ๊ณ ์ฐจ ์ปดํฌ๋„ŒํŠธ(HOC)๋Š” React API์˜ ์ผ๋ถ€๊ฐ€ ์•„๋‹ˆ๋ฉฐ, React์˜ ๊ตฌ์„ฑ์  ํŠน์„ฑ์—์„œ ๋‚˜์˜ค๋Š” ํŒจํ„ด์ž…๋‹ˆ๋‹ค.

 

//์ž์‹ ์ปดํฌ๋„ŒํŠธ
import React, {memo} from "react";

const Try = memo((props) => {
  return (
    <li>
      <div>{props.value.try}</div>
      <div>{props.value.result}</div>
    </li>
  );
});

Try.displayName = "Try";
//๋‹จ, memo๋ฅผํ•˜๊ฒŒ ๋˜๋ฉด ์ปดํฌ๋„ŒํŠธ์˜ ์ด๋ฆ„์ด ๋ณ€๊ฒฝ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ปดํฌ๋„ŒํŠธ์˜ ์ด๋ฆ„์„ ์ œ๋Œ€๋กœ ๋ณ€๊ฒฝ์‹œ์ผœ์ฃผ์–ด์•ผ ํ•œ๋‹ค.
export default Try;

 

 

 

 

  ์ด ์ฒ˜๋Ÿผ ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง์„ ๋ง‰์•„์ฃผ๋Š” ๊ธฐ๋Šฅ๋“ค์— ๋Œ€ํ•ด์„œ ์‚ดํŽด๋ณด์•˜๋‹ค! ์ •๋ฆฌํ•ด ๋ณด์ž๋ฉด React.Component๋กœ class๋ฅผ ํ™•์žฅํ•œ ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ์ด ์žˆ๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋ฆฌ๋ Œ๋”๋ง ๋˜๋„๋ก ํ•ด์ค„ ํ•„์š”๊ฐ€ ์žˆ์„๋•Œ๋Š” shouldComponentUpdate( )๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ณ , ๊ฐ„๋‹จํ•˜๊ฒŒ๋Š” React.PureComponent๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๊ณ  ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์ธ ๊ฒฝ์šฐ์—๋Š” props์˜ ๋ณ€๊ฒฝ์ด ์žˆ๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋ฆฌ๋ Œ๋”๋ง ๋˜๋„๋กํ•˜๋Š” React.memo๊ธฐ๋Šฅ์ด ์žˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ณด๋‹ค ์ตœ์ ํ™”๋ฅผ ์šฉ์ดํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค!