Deprecated

This API will be removed in a future major version of React. See the alternatives.

createFactory lets you create a function that produces React elements of a given type.

const factory = createFactory(type)

Reference

createFactory(type)

Call createFactory(type) to create a factory function which produces React elements of a given type.

import { createFactory } from 'react';

const button = createFactory('button');

Then you can use it to create React elements without JSX:

export default function App() {
return button({
onClick: () => {
alert('Clicked!')
}
}, 'Click me');
}

See more examples below.

Parameters

  • type: The type argument must be a valid React component type. For example, it could be a tag name string (such as 'div' or 'span'), or a React component (a function, a class, or a special component like Fragment).

Returns

Returns a factory function. That factory function receives a props object as the first argument, followed by a list of ...children arguments, and returns a React element with the given type, props and children.


Usage

Creating React elements with a factory

Although most React projects use JSX to describe the user interface, JSX is not required. In the past, createFactory used to be one of the ways you could describe the user interface without JSX.

Call createFactory to create a factory function for a specific element type like 'button':

import { createFactory } from 'react';

const button = createFactory('button');

Calling that factory function will produce React elements with the props and children you have provided:

import { createFactory } from 'react';

const button = createFactory('button');

export default function App() {
  return button({
    onClick: () => {
      alert('Clicked!')
    }
  }, 'Click me');
}

This is how createFactory was used as an alternative to JSX. However, createFactory is deprecated, and you should not call createFactory in any new code. See how to migrate away from createFactory below.


Alternatives

Copying createFactory into your project

If your project has many createFactory calls, copy this createFactory.js implementation into your project:

import { createFactory } from './createFactory.js';

const button = createFactory('button');

export default function App() {
  return button({
    onClick: () => {
      alert('Clicked!')
    }
  }, 'Click me');
}

This lets you keep all of your code unchanged except the imports.


Replacing createFactory with createElement

If you have a few createFactory calls that you donโ€™t mind porting manually, and you donโ€™t want to use JSX, you can replace every call a factory function with a createElement call. For example, you can replace this code:

import { createFactory } from 'react';

const button = createFactory('button');

export default function App() {
return button({
onClick: () => {
alert('Clicked!')
}
}, 'Click me');
}

with this code:

import { createElement } from 'react';

export default function App() {
return createElement('button', {
onClick: () => {
alert('Clicked!')
}
}, 'Click me');
}

Here is a complete example of using React without JSX:

import { createElement } from 'react';

export default function App() {
  return createElement('button', {
    onClick: () => {
      alert('Clicked!')
    }
  }, 'Click me');
}


Replacing createFactory with JSX

Finally, you can use JSX instead of createFactory. This is the most common way to use React:

export default function App() {
  return (
    <button onClick={() => {
      alert('Clicked!');
    }}>
      Click me
    </button>
  );
};

Pitfall

Sometimes, your existing code might pass some variable as a type instead of a constant like 'button':

function Heading({ isSubheading, ...props }) {
const type = isSubheading ? 'h2' : 'h1';
const factory = createFactory(type);
return factory(props);
}

To do the same in JSX, you need to rename your variable to start with an uppercase letter like Type:

function Heading({ isSubheading, ...props }) {
const Type = isSubheading ? 'h2' : 'h1';
return <Type {...props} />;
}

Otherwise React will interpret <type> as a built-in HTML tag because it is lowercase.