본문 바로가기
React

[React 스터디] 7 : 다른 라이브러리와 통합하기

by 바나냥 2020. 10. 12.

이 가이드는 jQuery와 Backbone의 통합에 중점을 맞추어 일반적인 몇 가지 사용 사례를 살펴봅니다. 동일한 아이디어로 기존 코드와 컴포넌트를 통합하는 데도 적용할 수 있습니다.

 

주의
이 방법이 가능하다고 해서 React 앱에 대한 최상의 접근 방법임을 의미하지는 않습니다. 가능하다면 React 컴포넌트를 사용하는 것을 권장합니다. React 컴포넌트는 React 애플리케이션에서 더 쉽게 재사용할 수 있으며, 해당 동작과 모양에 대해 더 많은 제어를 제공해 줍니다.

 

DOM 조작 플러그인과 통합하기

DOM에 영향을 미치는 다른 라이브러리와의 충돌을 피하기 위해 React 컴포넌트가 업데이트할 필요가 없는 빈 <div>를 렌더링한다.

componentDidMount 내부에서 jQuery 플러그인에 전달하기 위해 최상위 DOM 엘리먼트에 ref를 붙여 참조를 얻는다.

마운트 후 React가 DOM을 건드리는 것을 막기 위해 render()에 빈 div를 반환한다.

이렇게 하면 jQuery 플러그인이 DOM을 자유롭게 관리할 수 있다.

 

class SomePlugin extends React.Component {
  componentDidMount() {
    this.$el = $(this.el);
    this.$el.somePlugin();
  }

  componentWillUnmount() {
    this.$el.somePlugin('destroy');
  }

  render() {
    return <div ref={el => this.el = el} />;
  }
}

 

jQuery 플러그인은 DOM에 이벤트 리스너를 등록하므로 플러그인이 해제를 위한 메서드를 제공하지 않는다면 componentWillUnmount 안에서 해제해야 한다.

 

 

jQuery Chosen 플러그인과 통합하기

Chosen이 DOM에 무엇을 하는가? DOM 노드에서 Chosen을 호출하면 <select>를 인라인 스타일로 숨기고 <select> 바로 뒤에 <div class="chosen-container">로 감싸진 태그를 추가한다. 그리고 jQuery 이벤트를 통해 제어한다.

 

function Example() {
  return (
    <Chosen onChange={value => console.log(value)}>
      <option>vanilla</option>
      <option>chocolate</option>
      <option>strawberry</option>
    </Chosen>
  );
}

 

<Chosen>를 React 컴포넌트로 만든 API로 표현하면 위와 같다. 이를 <div>로 감싸인 <select>를 반환하는 빈 컴포넌트로 표현하면 아래와 같다.

React는 this.el 필드에 특별한 의미를 부여하지 않으며 render() 메서드에서 ref에 이 필드를 할당했기 때문에 작동한다.

 

class Chosen extends React.Component {
  render() {
    return (
      <div>
        <select className="Chosen-select" ref={el => this.el = el}>
          {this.props.children}
        </select>
      </div>
    );
  }
}

 

다음으로 componentDidMount에서 <select> 노드의 ref를 사용하여 Chosen을 초기화하고 componentWillUnmount에서 이를 해제해야 한다.

컴포넌트의 props가 여러 번 변경될 수 있으므로 Chosen에 this.props.onChange를 바로 전달하는 대신에 this.props.onChange를 호출하는 handleChange() 메서드를 선언하고 jQuery change 이벤트로 구독한다.

더 이상 React가 DOM을 관리하지 않으므로 prop이 업데이트 될 때 마다 수동으로 DOM을 업데이트해야 한다.

React로 <select> children을 관리하고 Chosen이 해당 DOM 엘리먼트 업데이트를 알게 된다.

 

componentDidMount() {
  this.$el = $(this.el);
  this.$el.chosen();

  this.handleChange = this.handleChange.bind(this);
  this.$el.on('change', this.handleChange);
}

componentDidUpdate(prevProps) {
    if (prevProps.children !== this.props.children) {
      this.$el.trigger("chosen:updated");
    }
 }

componentWillUnmount() {
  this.$el.off('change', this.handleChange);
  this.$el.chosen('destroy');
}

handleChange(e) {
  this.props.onChange(e.target.value);
}

 

아래는 Chosen 컴포넌트의 완전한 구현 모습

 

class Chosen extends React.Component {
  componentDidMount() {
    this.$el = $(this.el);
    this.$el.chosen();

    this.handleChange = this.handleChange.bind(this);
    this.$el.on('change', this.handleChange);
  }
  
  componentDidUpdate(prevProps) {
    if (prevProps.children !== this.props.children) {
      this.$el.trigger("chosen:updated");
    }
  }

  componentWillUnmount() {
    this.$el.off('change', this.handleChange);
    this.$el.chosen('destroy');
  }
  
  handleChange(e) {
    this.props.onChange(e.target.value);
  }

  render() {
    return (
      <div>
        <select className="Chosen-select" ref={el => this.el = el}>
          {this.props.children}
        </select>
      </div>
    );
  }
}

 

 

 

ko.reactjs.org/docs/integrating-with-other-libraries.html

 

다른 라이브러리와 통합하기 – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

댓글