Using non React components with React

Using non React components with React

Sometimes the cost of rewriting a UI component from scratch is no assumable in real-world projects. I am writing the front-end for a new application using React and Redux, but I find myself in the position of having to use components that are already tested and are not written with React in mind. How does React play with non-React components? Actually, quite well, but requires taking care of some points. The gist for the example is here.

React and the Virtual DOM

React biggest advantage is the use of a Virtual DOM. We write components in the Virtual DOM, and React updates the real DOM accordingly for us. When we update the Virtual DOM, React will calculate the differences with the previous state and render only the necessary changes to the real DOM. This makes interacting with the real DOM directly a problem, because if we don’t take care, we might break the sync between real and virtual DOMs. Luckily, React offers some methods in its Component API that make using non-React components quite easy.

Example: Using jQuery UI Slider with React

At work, even now we are slowly moving to React, we used jQuery UI a lot. We even created our own widgets using the jQuery UI Factory. That means that we have a lot of UI widgets that we want to continue using if possible, at least for now.

For our example, we will be using the Slider widget, and show the value of the slider using React. I will be using TypeScript, but the same principles are applicable to plain JavaScript or ES6.

Three React components

We will keep the project as simple as possible. We will create 3 components:

  • ReactSliderApp: The parent component, and the glue between our two child components
  • SliderValue: A pure React component, it only shows the slider value
  • JQueryUISlider: A React component that wraps and uses jQuery UI Slider widget

The gist can be found here.

Wrapping a non React component with React

Let’s take a closer look to the JQueryUISlider component:

class JQueryUISlider extends React.Component<JQueryUISliderProps, void> {
    componentDidMount() {
        const parent = ReactDOM.findDOMNode(this);
        const slider = $(parent).slider({
            min: 0,
            max: 100,
            value: this.props.value,
            change: (evt: Event, ui: any) => {
                this.props.onChange(ui.value);
            }
        });
    }
    componentWillUnmount() {
        const parent = ReactDOM.findDOMNode(this);
        $(parent).slider("destroy");
    }
    shouldComponentUpdate() {
        return false;
    }
    render() {
        return (
            <div></div>
        );
    }
}

There are 4 important steps that need to be taken care of when working with non React components in React.

First, the render() method creates the minimal barebones that our component needs. Normally just an element we can attach the UI component to. In our example, it is just a div element without any property.

Second, the componentDidMount() method. This method gets called after React has created the real DOM elements. It gets called only once in the lifetime of the component. Inside this method, we should set up the non React component. We can access the real DOM element by using the findDOMNode() method. If our element has a changing state, we should set up the event listeners and callbacks too, like we did with the slider’s change method.

Third, the componentWillUnmount() method. This method gets called before React is about to remove the real DOM elements. But since React does not know about our slider, we need to get rid of it. In the case of jQuery UI widgets, it is done by calling the destroy method.

Fourth, and probably the most important, the shouldComponentUpdate() method. This method allows us to override the default React behaviour of updating the component when the state changes. Because we are handling the changes to our element ourselves, we need to return false.

Conclusion

It is possible to use non React components when necessary, for example when migrating a legacy system to use React. There are thousands of non React JavaScript components that we can use, but we need to take care of handling their life cycle when using them with React.

Comments are closed.