This plugin can reduce React rerenders and garbage collection pressure by pulling
constant object attribute values (like style={{ color: 'red' }}
) out of functions
and into the highest possible scope. This means the objects will only get allocated once,
and they will keep the same identity across renders.
Objects are only pulled out if they are plain old data and don't reference any variables, so more dynamic use cases will still work as written.
In
const Component = () => <div style={{ color: 'red', fontSize: 14 }}>Text</div>;
Out
const _style = { color: 'red', fontSize: 14 };
const Component = () => <div style={_style}>Text</div>;
# npm
npm i --save-dev babel-plugin-hoist-constant-jsx-attributes
# yarn
yarn add --dev babel-plugin-hoist-constant-jsx-attributes
{
"plugins": [
["babel-plugin-hoist-constant-jsx-attributes", { /* options (see below) */ }]
]
}
RegExp
, or string
to be matched with micromatch
Only hoist attribute values if the element name matches.
RegExp
, or string
to be matched with micromatch
Only hoist attributes values if the element name does not match.
RegExp
, or string
to be matched with micromatch
Only hoist attribute values if the attribute name matches.
RegExp
, or string
to be matched with micromatch
Only hoist attributes values if the attribute name does not match.
boolean
, defaults to false
Only hoist object attribute values on primitive elements like div
and button
.
boolean
, defaults to false
By default, this plugin only hoists attribute values if the JSX element is contained
in a function or method. Using this option is not recommended, since otherwise the
problems this plugin solves don't occur. Setting this option to true
will hoist even
if the JSX element is at the top level.
false
, 'development'
, or 'always'
, defaults to false
.
If set to 'development'
, check at runtime to see if process.env.NODE_ENV === 'development'
,
and if so deeply freeze hoisted objects. If set to 'always'
, deeply
freeze hoisted objects unconditionally.
Use this option for extra safety if you want to ensure that the attribute values are never mutated. If there is an attempt to mutate a hoisted attribute value, an exception will be thrown. Slightly increases the compiled code size.
The React team considers this transformation unsafe to run by default, because it is possible to rely on object attribute values to have different identities every render. See this GitHub issue for more information.
However, the vast majority of cases will benefit from this transformation. The
main reason they consider it unsafe is precisely because it can reduce the number
of times a component rerenders, which is likely to be what you want. Unless you were
to intentionally tinker with object referential equality, or mutate received props
—and you would know if you were—this transformation will be safe.
Still, to be extra careful, you can set the lowerCaseOnly
plugin option to true
.
You can also set the freezeObjects
plugin option to 'development'
or 'always'
to receive an error if a component tries to mutate its props
.