Skip to content

Instantly share code, notes, and snippets.

@sebmarkbage
Last active March 15, 2020 00:32
Show Gist options
  • Save sebmarkbage/ae327f2eda03bf165261 to your computer and use it in GitHub Desktop.
Save sebmarkbage/ae327f2eda03bf165261 to your computer and use it in GitHub Desktop.
Use a factory or JSX

React Element Factories and JSX

You probably came here because your code is calling your component as a plain function call. This is now deprecated:

var MyComponent = require('MyComponent');

function render() {
  return MyComponent({ foo: 'bar' });  // WARNING
}

JSX

React components can no longer be called directly like this. Instead you can use JSX.

var React = require('react');
var MyComponent = require('MyComponent');

function render() {
  return <MyComponent foo="bar" />;
}

Without JSX

If you don't want to, or can't use JSX, then you'll need to wrap your component in a factory before calling it:

var React = require('react');
var MyComponent = React.createFactory(require('MyComponent'));

function render() {
  return MyComponent({ foo: 'bar' });
}

This is an easy upgrade path if you have a lot of existing function calls.

Dynamic components without JSX

If you get a component class from a dynamic source, then it might be unnecessary to create a factory that you immediately invoke. Instead you can just create your element inline:

var React = require('react');

function render(MyComponent) {
  return React.createElement(MyComponent, { foo: 'bar' });
}

In Depth

Read more about WHY we're making this change.

@mlmorg
Copy link

mlmorg commented Dec 11, 2014

@darcyadams I ended up writing a hyperscript syntax wrapper around React.createElement which prevents the unnecessary use of React.createFactory and can also, hopefully, prevent future breaking changes from affecting the interface. -- https://github.com/mlmorg/react-hyperscript

@mikew
Copy link

mikew commented Dec 11, 2014

like @mimorg, I use a couple of methods that allows for these "hyperscript" (haml, jade, whatever you want to call them) strings.

In addition to react-hyperscript, it allows use if a percent sign for refs:

parseTagName("%foo#bar.baz")
// { tagName: 'div', refName: 'foo', id: 'bar', className: 'baz' }

and it has its own createFactory, which is helpful in Array.prototype.map:

var users = [] // from elsewhere
createElement('div', null, users.map(createFactory('div.user--container')))

There is also a store of named components, so you're not limited to the React.DOM items when using string names, which also removes the need for requireing common components in many files.

This is it extracted from the framework we're using at work
https://gist.github.com/mikew/e737273e42ed704c6c54

@Bargs
Copy link

Bargs commented Dec 13, 2014

@ghost23 I saw the same warnings before I upgraded Reactify. The newest version of Reactify uses react-tools v0.12.1 just like you said you're using, but I noticed that the generated JS is now using the new React API (React.createElement) instead of calling the components directly. I would check to make sure the JSX is being compiled with the most up to date tools.

@johdah
Copy link

johdah commented Feb 23, 2015

How would I do this if I use the following way to load my dependencies?

require(['lodash', "jquery", "jquery-ui/ui/dialog", 'react', 'lib/react/forms/selectField'], 
     function(_, jQuery, jQueryDialog, React, SelectField) {

If i use your new way of doing it, it would complain that I load it the wrong way and if I remove the occurrences in the wrapping require call it would complain that it isn't loaded when I try to use:

var SelectField = React.createFactory(require('lib/react/forms/selectField'));

@BoldBigflank
Copy link

I'm getting this warning from the very most basic tutorial code. What is supposed to be different?

/**
 * @jsx React.DOM
 */

var Hello = React.createClass({
    render: function() {
        return <div>Hello {this.props.name}</div>;
    }
});

React.render(<Hello name="World" />, document.getElementById('container'));

@soruban
Copy link

soruban commented Oct 27, 2015

@BoldBigflank, do you still get the warning if you go with es6?

class Hello extends React.Component {
    render() {
        return <div>Hello {this.props.name}</div>;
    }
}

React.render(<Hello name="World" />, document.getElementById('container'));

@arkhamRejek
Copy link

The return sometimes needs to be wrapped in braces

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment