React can be applied to any Web application, embedded in other applications, and other applications can also be embedded in React. Here’s how React works with other libraries.
Integrate plug-ins with DOM manipulation
React doesn’t care about DOM operations outside of React itself. It uses the internal virtual DOM to determine whether it needs to be updated, and if the same DOM node is operated on by another library, React gets confused and has no way to recover it. The easiest way to avoid collisions is to prevent the React component from updating.
How to solve this problem
For example, a wrapper for a generic JQuery plugin, first add a ref to the root DOM element, then get a reference to the DOM element in componentDidMount, and pass it to the JQuery plugin. To prevent Reacat from touching the DOM after it is mounted, our render function returns an empty <div />. The div element has no attributes or child elements, so React has no reason to update it, leaving the Jquery plugin free to manage that part of the DOM. We defined both componentDidMount and componentWillUnmount life cycle functions because we had to log out after binding to avoid memory leaks.
Integrate JQuery Chosen plug-in
The following example will write a wrapper to the Chosen plug-in used to enhance select input.
What does Chosen do to the DOM?
- Read the property of the original DOM node, then hide it with inline styles.
- Next to this select, add a separate DOM node with its own display.
- When a value changes, a JQuery event is triggered to notify us of the change.
What you want to achieve in the end
function Example() {
return (
<Chosen onChange={value= > console.log(value)}>
<option>vanilla</option>
<option>chocolate</option>
<option>strawberry</option>
</Chosen>
);
}
Copy the code
- Start by creating an empty component whose render function returns a div containing a select
class Chosen extends React.Component {
render() {
return (
<div>
<select className="Chosen-select" ref={el= > this.el = el}>
{this.props.children}
</select>
</div>); }}Copy the code
-
The reason we want to wrap the select with an extra div is because we said that Chosen appends a DOM element right next to the select node we pass to it. However, React dictates that a component can only have one root DOM element, so wrapping it around a div won’t cause the React update to collide with the extra DOM nodes Chosen appended.
-
The implementation declares periodic functions
componentDidMount() {
this.$el = $(this.el);
this.$el.chosen();
}
componentWillUnmount() {
this.$el.chosen('destroy');
}
Copy the code
- Implementations are notified when values change, requiring the JQuery change event on the Chosen managed select subscription. You do not pass this.props. OnChange directly to Chosen because the props of the component can change at any time and also include event handlers. We call this.props. OnChange by defining a handleChange method and subscribing to JQuery’s change event:
componentDidMount() {
this.$el = $(this.el);
this.$el.chosen();
this.handleChange = this.handleChange.bind(this);
this.$el.on('change'.this.handleChange);
}
componentWillUnmount() {
this.$el.off('change'.this.handleChange);
this.$el.chosen('destroy');
}
handleChange(e) {
this.props.onChange(e.target.value);
}
Copy the code
- The documentation for Chosen suggests that we use JQuery trigger() to notify the raw DOM element of these changes, and we need to add a componentDidUpdate lifecycle function to notify Chosen of changes to the children list.
componentDidUpdate(prevProps) {
if(prevProps.children ! = =this.props.children) {
this.$el.trigger("chosen:updated"); }}Copy the code
- The complete implementation of the Chosen component
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>); }}Copy the code
Integrate with other view libraries
React can be embedded in other applications thanks to the flexibility of reactdom.render ().
React replaces string-based rendering
- It is common to use strings to render the DOM in older Web applications, such as the following example, which is suitable for introducing React. We can rewrite the string based rendering as the React component directly.
$('#container').html('<button id="btn">Say Hello</button>');
$('#btn').click(function() {
alert('Hello! ');
});
Copy the code
- Rewrite using the React component
function Button() {
return <button id="btn">Say Hello</button>;
}
ReactDOM.render(
<Button />.document.getElementById('container'),
function() {$('#btn').click(function() {
alert('Hello! '); }); });Copy the code
- Use the React event system to register click handlers directly into the React Button element
function Button(props) {
return <button onClick={props.onClick}>Say Hello</button>;
}
function HelloButton() {
function handleClick() {
alert('Hello! ');
}
return <Button onClick={handleClick} />;
}
ReactDOM.render(
<HelloButton />.document.getElementById('container'));Copy the code
Embed React in Backbone view
- Backbone is the process of creating DOM elements using HTML strings or template functions that generate strings. This process can also be replaced by rendering a React component. Next we create a Backbone view called ParagraphView, which overrides the Render function to render a React Paragraph component into a Backbone DOM element, where we still need to use reactdom.render ().
function Paragraph(props) {
return <p>{props.text}</p>;
}
const ParagraphView = Backbone.View.extend({
render() {
const text = this.model.get('text');
ReactDOM.render(<Paragraph text={text} />.this.el);
return this;
},
remove() {
ReactDOM.unmountComponentAtNode(this.el);
Backbone.View.prototype.remove.call(this); }});Copy the code
When a component in the React tree delete, from internal cleaning work is done automatically, but because we are now manually removed the entire tree, so you must call ReactDOM. UnmountComponentAtNode ().
Integration with the Model layer
The React component can also use the Model layer of other frameworks and libraries.
Use Backbone Modal in the React component
The easiest way to use Backbone Model and Collection in React is to listen for multiple change events and manually force an update.
class Item extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); } handleChange() { this.forceUpdate(); } componentDidMount() { this.props.model.on('change', this.handleChange); } componentWillUnmount() { this.props.model.off('change', this.handleChange); } render() { return <li>{this.props.model.get('text')}</li>; } } class List extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); } handleChange() { this.forceUpdate(); } componentDidMount() { this.props.collection.on('add', 'remove', this.handleChange); } componentWillUnmount() { this.props.collection.off('add', 'remove', this.handleChange); } render() { return ( <ul> {this.props.collection.map(model => ( <Item key={model.cid} model={model} /> ))} </ul> ); }}Copy the code