Broken React.createClass Component? Let’s Fix It!

If you are building WordPress Gutenberg Blocks (or even if you are not) you may be trying to get a third party React Component working in your build. But if it’s an older element, specifically one that uses the deprecated React.createClass method, you may get stuck.

The files that accompany this tutorial are in the original and patched folders in the components folder of the GitHub solution.

Get Tutorial Files from GitHub

I was looking for a checkbox list that allowed me to pass an array of options (similar to how you might pass multiple options to the <SelectControl/> in WordPress Gutenberg). The built in <CheckboxControl/>didn’t have an option, but after some searching the web I found react-checkbox-list by Sony An (available as react-checkbox-list on npm).

This did everything I wanted it to do, but after installing it via npm (npm install react-checkbox-list --save) it didn’t work. I knew I would have to fork and patch the plugin.

Note that this tutorial covers patching the existing React.createClass and React.propTypes methods. If you are interested in learning how to patch them with the preferred method of using React.Component please view the post on that topic.

Patching the React Component

The first issue you will come across is that the component will not even load, and you will be presented with a rather nasty Uncaught TypeError: Cannot read property 'array' of undefined error.

Uncaught TypeError, Cannot read property 'array' of undefined
Uncaught TypeError, Cannot read property ‘array’ of undefined

This is because the Component contains the following line defaultData: React.PropTypes.array, and it is because React.PropTypes that is undefined.

React.PropTypes is undefined
React.PropTypes is undefined

A bit of investigation into the React documentation shows that React.PropTypes moved into a different package in React version 15.5. It advises us to use the prop-types library instead.

It even gives you a link to the npm repository for the prop-types library. So lets go ahead and install the prop-types library.

npm install --save prop-types

At the top of our document, let’s import the prop-types library. The modern way of this would have us use the import syntax, but for now, let’s keep to the same syntax add var PropTypes = require('prop-types'); to the document below where we declare React. The opening declaration should now look a little something like this:

'use strict';
var React     = require('react');
var PropTypes = require('prop-types');

module.exports = React.createClass({
	displayName: 'CheckBoxList',

	propTypes: {
		defaultData: React.PropTypes.array,
		onChange: React.PropTypes.func
	},
...

Great stuff! However we still get the 'array' of undefined error message. Well thats because the syntax being used is React.PropTypes.array and we just declared our PropTypes to use the variable PropTypes. So the simple fix is to find and replace all instances of React.PropTypes with PropTypes.

Our opening block of code should now look like this:

'use strict';
var React     = require('react');
var PropTypes = require('prop-types');

module.exports = React.createClass({
	displayName: 'CheckBoxList',

	propTypes: {
		defaultData: PropTypes.array,
		onChange: PropTypes.func
	},
...

There we go, our PropTypes issue is now resolved! Lets refresh our component and see if it works.

Nope, we now get the error Uncaught TypeError: React.createClass is not a function.

Uncaught TypeError: React.createClass is not a function.
Uncaught TypeError: React.createClass is not a function.

Again, a little search around the React documentation and release notes for v15.5.0 shows us that React.createClass was depreciated in version 15.5.0.

Along with React.PropTypes, React.createClass was refactored into its own package, as the preferred method of creating React Components uses React.Component.

The replacement for React.createClass is now in its own npm repository as create-react-class. So let’s go ahead and install this into our build.

npm install --save create-react-class

We need to import the package into our build, again keeping the syntax in the classic format add the line var CreateReactClass = require('create-react-class'); to the top of the document, like so:

'use strict';
var React            = require('react');
var PropTypes        = require('prop-types');
var CreateReactClass = require('create-react-class');

module.exports = React.createClass({
	displayName: 'CheckBoxList',

	propTypes: {
		defaultData: PropTypes.array,
		onChange: PropTypes.func
	},
...

Again, our error won’t go away, because we need to replace all instances of React.createClass with our new imported object CreateReactClass. That should look a little bit like this:

'use strict';
var React            = require('react');
var PropTypes        = require('prop-types');
var CreateReactClass = require('create-react-class');

module.exports = CreateReactClass({
	displayName: 'CheckBoxList',

	propTypes: {
		defaultData: PropTypes.array,
		onChange: PropTypes.func
	},
...

And thats it! The component no longer errors, and our JavaScript console is nice and clean.

The finished solution looks a little like this:

The Patched React Multiple Checklist Component In WordPress Gutenberg
The Patched React Multiple Checklist Component In WordPress Gutenberg

Tutorial Source Code

You can download the source code for the original and patched version of the component on GitHub. The plugin contains a WordPress Gutenberg block that you can use to play around with the code, with three files that you can delete as applicable:

The GitHub Tutorial Files for the React.createClass patch
The GitHub Tutorial Files for the React.createClass patch

Submitting a Pull Request to the Original Repository

The great thing about the open source community is that we are free to contribute and improve code. Here is the Pull Request with the patch that I have just created that I have submitted to Sony An.

Posted by Matt Watson

Matt Watson loves to talk about Health, Wealth and Code (mainly WordPress). Get in touch with Matt or follow Matt on Twitter to get notified about his latest posts.