React JSX Parser
`react-jsx-parser` is a React component designed to parse JSX provided as a string and render it into actual React components. The current stable version is 2.4.1, which includes improvements for unary operator support, error handling, and TypeScript typings. The library maintains a regular release cadence with recent minor updates. A significant major release (v2.0.0) introduced compatibility with React 18+. Key differentiators include its ability to dynamically render React components from string-based JSX, its explicit prevention of inline function declarations within the parsed JSX to mitigate XSS attack vectors, and its robust support for various binding types (implicit boolean, string, expression, and named-value bindings). It seamlessly handles component collections and dot-notation for nested components, making it suitable for dynamic content rendering where JSX is sourced from external data.
Common errors
-
Error: Functions are not allowed to be parsed inline.
cause Attempting to use an inline function declaration (e.g., `onClick={() => {}}` or `onPress={function() {}}`) directly within the `jsx` prop string passed to `JsxParser`.fixDefine the function in the `bindings` prop of `JsxParser` and reference its name within the `jsx` string. Example: `<JsxParser bindings={{ myHandler: () => console.log('clicked') }} jsx='<button onClick={myHandler}>Click me</button>' />`. -
React.Children.only expected to receive a single React element child.
cause This error or similar rendering issues (e.g., `_react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx is not a function`) often occur when `react-jsx-parser` v1.x is used in a project that has upgraded to React 18.fixUpgrade `react-jsx-parser` to version 2.0.0 or higher to ensure compatibility with React 18's updated rendering mechanisms. Run: `npm install react-jsx-parser@^2`.
Warnings
- breaking Upgrading to React 18 requires `react-jsx-parser` version 2.0.0 or higher. Previous versions (v1.x) are incompatible with React 18's new concurrent rendering features and will lead to errors.
- gotcha Inline function declarations (e.g., arrow functions or anonymous functions directly in props like `onClick={() => {...}}`) are explicitly disallowed within the `jsx` string. This is a deliberate security measure to prevent XSS vulnerabilities when parsing untrusted JSX.
- gotcha Support for components containing dot notation in their names (e.g., `<Form.Field />`) was introduced in version 2.4.0. If you encounter issues parsing such components, your version may be too old.
Install
-
npm install react-jsx-parser -
yarn add react-jsx-parser -
pnpm add react-jsx-parser
Imports
- JsxParser
const JsxParser = require('react-jsx-parser')import JsxParser from 'react-jsx-parser'
- React
import React from 'react'
- JsxParserProps
import type { JsxParserProps } from 'react-jsx-parser'
Quickstart
import React from 'react';
import JsxParser from 'react-jsx-parser';
// A mock component from 'some-library-of-components'
const Library = {
SomeComponent: ({ someProp, calc, stringProp, children }) => (
<div>
<h3>Library.SomeComponent</h3>
<p>Prop A: {someProp}</p>
<p>Calc: {calc}</p>
<p>String Prop: {stringProp}</p>
{children && children({ name: 'Fetched Data' })}
</div>
),
DataFetcher: ({ children }) => (
<div>
<h4>Library.DataFetcher</h4>
{children && children({ name: 'Dynamic Data' })}
</div>
),
};
// An injectable custom component
const InjectableComponent = ({ eventHandler, truthyProp }) => {
return (
<div onClick={eventHandler} style={{ border: '1px solid gray', padding: '10px', margin: '10px' }}>
<p>Injectable Component</p>
<p>Truthy Prop: {String(truthyProp)}</p>
<button onClick={eventHandler}>Trigger Event</button>
</div>
);
};
const MyParsedComponent = () => (
<JsxParser
bindings={{
foo: 'bar',
myEventHandler: () => {
console.log('Event handler triggered!');
alert('Hello from event handler!');
},
}}
components={{ InjectableComponent, Library }}
jsx={`
<h1>Header from Parsed JSX</h1>
<InjectableComponent eventHandler={myEventHandler} truthyProp />
<Library.SomeComponent someProp={foo} calc={1 + 1} stringProp="hello world">
{(data) => <div>Data from children: {data.name}</div>}
</Library.SomeComponent>
<Library.DataFetcher>((data) => <div>Fetched Data Name: {data.name}</div>)</Library.DataFetcher>
<p>This is a standard HTML paragraph.</p>
`}
/>
);
export default MyParsedComponent;