이 가이드는 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' 카테고리의 다른 글
styled-components 라이브러리 만들기 (0) | 2020.10.16 |
---|---|
[error] 저장시 eslint 자동으로 fix되지 않음 (0) | 2020.10.16 |
SVG 파일을 컴포넌트로 만들기 (0) | 2020.10.06 |
[React 스터디] 6 : 고차 컴포넌트 (0) | 2020.09.28 |
useState를 사용한 배열 set (0) | 2020.09.22 |
댓글