forked from vasanthk/react-bits
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path26.third-party-integration.jsx
86 lines (73 loc) · 2.77 KB
/
26.third-party-integration.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/**
* Mixing 3rd party integrations/libraries with React
*
* @Reference:
* https://github.com/krasimir/react-in-patterns/tree/master/patterns/third-party
*/
// In this example we'll see how to mix React and jQuery's UI plugin.
// We pick tag-it jQuery plugin for the example. It transforms an unordered list to input field for managing tags:
//
// <ul>
// <li>JavaScript</li>
// <li>CSS</li>
// </ul>
//
// To make it work we have to include jQuery, jQuery UI and the tag-it plugin code. It works like that:
$('<dom element selector>').tagit();
//We select a DOM element and call tagit().
// The very first thing that we have to do is to force a single-render of the Tags component.
// That's because when React adds the elements in the actual DOM we want to pass the control of them to jQuery.
// If we skip this both React and jQuery will work on same DOM elements without knowing for each other. To achieve a single-render we have to use the lifecycle method shouldComponentUpdate
//
// Let's say that we want to programmatically add a new tag to the already running tag-it field.
// Such action will be triggered by the React component and needs to use the jQuery API.
// We have to find a way to communicate data to Tags component but still keep the single-render approach.
// To illustrate the whole process we will add an input field to the App class and a button which if clicked will pass a string to Tags component.
class App extends React.Component {
constructor(props) {
super(props);
this._addNewTag = this._addNewTag.bind(this);
this.state = {
tags: ['JavaScript', 'CSS'],
newTag: null
};
}
_addNewTag() {
this.setState({newTag: this.refs.field.value});
}
render() {
return (
<div>
<p>Add new tag:</p>
<div>
<input type='text' ref='field'/>
<button onClick={ this._addNewTag }>Add</button>
</div>
<Tags tags={ this.state.tags } newTag={ this.state.newTag }/>
</div>
);
}
}
// We use the internal state as a data storage for the value of the newly added field.
// Every time when we click the button we update the state and trigger re-rendering of Tags component.
// However, because of shouldComponentUpdate we update nothing.
// The only one change is that we get a value of the newTag prop which may be captured via another lifecycle method - componentWillReceiveProps
class Tags extends React.Component {
componentDidMount() {
this.list = $(this.refs.list);
this.list.tagit();
}
shouldComponentUpdate() {
return false;
}
componentWillReceiveProps(newProps) {
this.list.tagit('createTag', newProps.newTag);
}
render() {
return (
<ul ref='list'>
{ this.props.tags.map((tag, i) => <li key={ i }>{ tag } </li>) }
</ul>
);
}
}