[React] High-order Component

๊ฐ•์€๋น„ยท2022๋…„ 1์›” 19์ผ
0

React

๋ชฉ๋ก ๋ณด๊ธฐ
27/36
post-thumbnail
post-custom-banner

๐Ÿ“Œ HoC

High-order Component (๊ณ ์ฐจ ์ปดํฌ๋„ŒํŠธ)

  • ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋‹ค๋ณด๋ฉด, ์ž์ฃผ ๋ฐ˜๋ณตํ•ด์„œ ์ž‘์„ฑํ•˜๊ฒŒ ๋˜๋Š” ์ฝ”๋“œ๋“ค์ด ์žˆ๋‹ค. ์ฃผ๋กœ ๊ทธ๋Ÿฐ ์ฝ”๋“œ๋“ค์„ ํ•จ์ˆ˜ํ™”ํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.
  • ์ปดํฌ๋„ŒํŠธ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ด๋‹ค. ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ๋ฐ˜๋ณต๋˜๋Š” ์ฝ”๋“œ๋“ค์€, Hoc์„ ๋งŒ๋“ค์–ด์„œ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.
  • HOC๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ€์ ธ์™€ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์ƒˆ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.
  • ์ปดํฌ๋„ŒํŠธ ๋กœ์ง์„ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.

โœจ ๋ฐ˜๋ณต๋˜๋Š” ์ฝ”๋“œ

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

class Post extends Component {
  state = {
    data: null
  }
  
  async initialize() {
    try {
      const response = await axios.get('https://jsonplaceholder.typicode.com/posts/1');
      this.setState({
        data: response.data
      });
    } catch (e) {
      console.log(e);
    }
  }

  componentDidMount() {
    this.initialize();  
  }


  render() {
    const { data } = this.state;
    
    if (!data) return null;

    return (
      <div>
        { JSON.stringify(data) }    
      </div>
    );
  }
}

export default Post;
// Comments.js
import React, { Component } from 'react';
import axios from 'axios';

class Comments extends Component {
  state = {
    data: null
  }

  async initialize() {
    try {
      const response = await axios.get('https://jsonplaceholder.typicode.com/comments?postId=1');
      this.setState({
        data: response.data
      });
    } catch (e) {
      console.log(e);
    }
  }

  componentDidMount() {
    this.initialize();
  }


  render() {
    const { data } = this.state;

    if (!data) return null;

    return (
      <div>
        {JSON.stringify(data)}
      </div>
    );
  }
}


export default Comments;

โœจ HoC ์ž‘์„ฑํ•˜๊ธฐ

  • ๋ฐ˜๋ณต๋˜๋Š” ์ฝ”๋“œ๋ฅผ ์—†์• ๊ธฐ ์œ„ํ•ด ํ•˜๋‚˜์˜ ํ•จ์ˆ˜, HoC์„ ์ž‘์„ฑํ•œ๋‹ค.
  • ์ฃผ๋กœ HoC์˜ ์ด๋ฆ„์„ ๋งŒ๋“ค ๋•Œ with_ ํ˜•์‹์œผ๋กœ ์ง“๋Š”๋‹ค.

    ๐Ÿ’ก ์ธ์ž๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฐ›๊ณ , ์ƒˆ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋ฐ˜ํ™˜๋œ ์ปดํฌ๋„ŒํŠธ ์•ˆ์—์„œ ์ธ์ž๋กœ ๋ฐ›์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•œ๋‹ค. ์ด๋•Œ ์ธ์ž๋กœ ๋ฐ›์€ ์ปดํฌ๋„ŒํŠธ์˜ ์›๋ž˜ props ๋“ค์„ ๊ทธ๋Œ€๋กœ ์ „๋‹ฌํ•˜๊ณ , ํ•„์š”์— ๋”ฐ๋ผ ์ถ”๊ฐ€ props๋„ ๋„ฃ์–ด์ค€๋‹ค.

โ— Closure ๊ฐœ๋…์ด ์‚ฌ์šฉ๋˜์—ˆ๋‹ค. HoC์ด ์ข…๋ฃŒ๋˜์–ด๋„ ๋ฐ˜ํ™˜๋œ ์ปดํฌ๋„ŒํŠธ๋Š” Hoc์ด ์ธ์ž๋กœ ๋ฐ›์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ธฐ์–ตํ•ด์•ผ ํ•œ๋‹ค!

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

const withRequest = (url) => (WrappedComponent) => {
  return class extends Component {
    state = {
       data: null
    }
    async initialize(){
       try{
           const response = await axios.get(url); // url๋ฅผ ๊ธฐ์–ตํ•ด์•ผ ํ•จ.
           this.setState({
              data: response.data
           });
       }
       catch(e){
           console.log(e);
       }
    }
    
    componentDidMount(){
        this.initialize();
    }
    
    render() {
      const { data } = this.state;
      return (
        <WrappedComponent {...this.props} data={data}/> // WrapperComponent๋ฅผ ๊ธฐ์–ตํ•ด์•ผ ํ•จ.
      )
    }
  }
}

export default withRequest;

โœจ HoC ์‚ฌ์šฉํ•˜๊ธฐ

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

class Post extends Component {
  render() {
    const { data } = this.props;
    
    if (!data) return null;

    return (
      <div>
        { JSON.stringify(this.props.data) }    
      </div>
    );
  }
}


export default withRequest('https://jsonplaceholder.typicode.com/posts/1')(Post);
import React, { Component } from 'react';
import withRequest from './withRequest';

class Comments extends Component {
  render() {
    const { data } = this.props;

    if (!data) return null;

    return (
      <div>
        {JSON.stringify(data)}
      </div>
    );
  }
}


export default withRequest('https://jsonplaceholder.typicode.com/comments?postId=1')(Comments);

โ— ๊ณ ์ฐจ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋ฆฌ๋•์Šค์˜ connetํ•จ์ˆ˜์™€ ๋งค์šฐ ์œ ์‚ฌํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฝ์–ด๋ณด๋‹ˆ connectํ•จ์ˆ˜์—์„œ ๊ณ ์ฐจ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ด์šฉํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

post-custom-banner

0๊ฐœ์˜ ๋Œ“๊ธ€