Lined Notebook

고차 컴포넌트

by yjym33

고차 컴포넌트란?

 

Higher-order Component (HOC)

즉 컴포넌트 내에서 자주 반복되는 코드를 재사용하기 위한 React 기술

 

const EnhancedComponent = higherOrderComponent(WrappedComponent);

 

기존 컴포넌트가 props를 받아 UI를 만들었다면, HOC는 컴포넌트를 다른 컴포넌트로 바꿉니다.

HOC는 Redux’s connect, Realy’s createFragmentContainer에서 흔히 사용하고 있습니다.

리액트에서 컴포넌트는 코드 재사용을 위한 매우 중요한 유닛입니다.

 

반복되는 코드 발견하기

 

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;

// post.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;

// comments.js

둘의 코드 내용은 거의 같습니다. 우선 이렇게 반복되는 코드를 찾는것이 첫번째 순서입니다.

 

HOC 작성하기

 

우리는 이 반복되는 코드를 없애기 위해서 하나의 함수를 작성합니다.

주로 HOC 의 이름을 만들땐 with_____ 형식으로 짓습니다.

예를들어, 우리는 웹요청을 하는 HOC 를 만들테니 withRequest 라고 지어주도록 하겠습니다.

 

HOC 의 원리는, 파라미터로 컴포넌트를 받아오고, 함수 내부에서 새 컴포넌트를 만든 다음에 해당 컴포넌트 안에서 파라미터로 받아온 컴포넌트를 렌더링하는 것입니다. 그리고, 자신이 받아온 props 들은 그대로 파라미터로 받아온 컴포넌트에게 다시 주입해주고, 필요에 따라 추가 props 도 넣어줍니다 

 

우선 HOC의 틀을 작성해줍니다.

 

WithRequest.js

import React, { Component } from 'react';

const withRequest = (url) => (WrappedComponent) => {
  return class extends Component {
    render() {
      return (
        <WrappedComponent {...this.props}/>
      )
    }
  }
}

export default withRequest;

위 코드를 보면, 함수에서 또 다른 함수를 리턴하도록 했습니다. (url, WrappedComponent) 형식이 아니라

(url) => (WrappedComponent) 로 한 이유는, 나중에 여러개의 HOC 를 합쳐서 사용하게 될 때 더욱 편하게 사용하기 위함입니다.

 

이제 다음은 틀만 만들었던 HOC에 기능을 넣어줍니다.

 

WithRequest.js

import React, { Component } from 'react';
import axios from 'axios';

const withRequest = (url) => (WrappedComponen) => {
  return class extends Component {

    state = {
      data: null
    }

    async initialize() {
      try {
        const response = await axios.get(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}/>
      )
    }
  }
}

export default withRequest;

 

HOC 사용하기

 

Post.js

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);

Comments.js

 

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);

 

이렇게 HOC 를 사용함으로서, 반복되는 코드들이 많이 사라졌습니다. 이렇게 웹요청을 하는 외에도, LifeCycle 메소드를 붙여준다던지, Redux 에서 특정 값을 받아와서 주입해준다던지, 다국어지원을 한다던지 여러가지 일들을 할 수 있습니다.

recompose 라는 라이브러리는, 페이스북 개발자가 만든 유용한 HOC 컬렉션 라이브러리인데요, 활용하면 매우 쓸모있습니다. 종류는 굉장히 많은데, 이제 HOC 가 어떤 역할을 하는지 알았으니, recompose 의 API 문서 를 쭉 훑어보시면 어떤 것들을 할 수있는지 감을 잡으실 수 있을 것입니다.

'Development > React' 카테고리의 다른 글

React Hooks (2)  (0) 2021.06.04
React - Hooks (1)  (0) 2021.05.14
컴포넌트의 라이프사이클 메서드 (2)  (0) 2021.05.11
컴포넌트의 라이프 사이클 메서드 (1)  (0) 2021.05.10
컴포넌트 반복  (0) 2021.05.10

블로그의 정보

생각보다 실천을

yjym33

활동하기