React JSON Editor Component
json-edit-react is a highly configurable React component designed for both viewing and interactively editing JSON or arbitrary JavaScript object data. It provides features like inline editing, granular control over edit/delete/add permissions per element, optional JSON Schema validation (with a third-party library), and extensive UI customization through themes and CSS. The package, currently at version 1.29.0, receives frequent minor and patch updates, indicating active maintenance and ongoing feature development. Key differentiators include its self-contained nature (minimal external UI dependencies), search and filtering capabilities, support for custom components to render specific node types, localization, and drag-and-drop re-ordering. It offers a comprehensive solution for applications requiring dynamic JSON data manipulation within a React environment.
Common errors
-
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
cause This error often occurs when the `JsonEditor` component is imported incorrectly or when the `theme` prop receives an invalid value (e.g., a string instead of an imported theme object after v1.19.0).fixEnsure `import { JsonEditor } from 'json-edit-react';` is correct. If using themes, verify that `import { yourThemeName } from 'json-edit-react/themes';` is used and the theme object is passed as `{theme={yourThemeName}}`. -
Cannot read properties of undefined (reading 'map') or 'forEach'
cause Often indicates that the `data` prop passed to `JsonEditor` is `undefined`, `null`, or not a valid object/array when the component expects one, especially during initial render or asynchronous data loading.fixEnsure the `data` prop always receives a valid JavaScript object or array. Initialize your state with an empty object `{}` or array `[]` if the data is fetched asynchronously, or conditionally render the `JsonEditor` component only when `data` is available. -
Unhandled Runtime Error: A component is changing an uncontrolled input of type [text/number] to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa).
cause While less common directly from `json-edit-react`, this can arise if an external state update (e.g., from `setData`) interferes with an internal input element's state within the editor, especially if `data` is mutated directly rather than creating a new object.fixEnsure that any updates to the `data` prop passed to `JsonEditor` are done immutably (e.g., using spread syntax `...` to create new objects/arrays) to avoid unexpected re-renders or state conflicts. The `setData` prop provided by `json-edit-react` typically handles this correctly.
Warnings
- breaking The way themes are applied changed in v1.19.0. Instead of passing a theme name as a string (e.g., `theme="dark"`), you must now explicitly import the theme object and pass it (e.g., `theme={darkTheme}`). This change was implemented for better tree-shaking.
- gotcha When handling data updates, it is recommended to use the `setData` prop for external updates rather than relying solely on the `onUpdate` prop, especially since v1.14.0. This ensures proper state management within React.
- gotcha Displaying and editing very large JSON objects (e.g., hundreds of thousands of keys/values or deeply nested structures) can lead to performance issues due to React's rendering cycle and the component's interactive features. Users might experience UI lag.
- gotcha The `json-edit-react` component, while flexible, may not automatically handle custom object types (like `Date`, `Map`, `Set`) as distinct editable entities without explicit configuration. By default, these might be stringified or treated as plain objects, potentially losing type fidelity.
- gotcha The v1.29.0 release introduced an option for '1-indexed arrays' display. If enabled, this changes how array indices are presented in the UI (starting from 1 instead of 0), which might confuse users accustomed to 0-indexed arrays in programming contexts. It is a display-only option and does not change the underlying data structure.
Install
-
npm install json-edit-react -
yarn add json-edit-react -
pnpm add json-edit-react
Imports
- JsonEditor
const JsonEditor = require('json-edit-react');import { JsonEditor } from 'json-edit-react'; - BuiltInThemes
import { 'dark' } from 'json-edit-react/themes';import { BuiltInThemes } from 'json-edit-react'; - JsonEditorProps
import type { JsonEditorProps } from 'json-edit-react';
Quickstart
import React, { useState, useCallback } from 'react';
import { JsonEditor } from 'json-edit-react';
// Import a built-in theme (since v1.19.0)
import { darkTheme } from 'json-edit-react/themes';
function MyJsonEditorComponent() {
const [jsonData, setJsonData] = useState({
user: {
id: 1,
name: "Alice Smith",
email: "alice@example.com",
isActive: true,
roles: ['admin', 'editor'],
settings: {
theme: 'dark',
notifications: true,
dataLimit: 1000
}
},
products: [
{ id: 'a1', name: 'Laptop', price: 1200 },
{ id: 'b2', name: 'Mouse', price: 25 }
]
});
// Callback to handle changes from the editor
const handleDataChange = useCallback((updatedData) => {
console.log('JSON data updated:', updatedData);
setJsonData(updatedData);
}, []);
return (
<div style={{ maxWidth: '800px', margin: '20px auto', padding: '20px', border: '1px solid #ccc', borderRadius: '8px' }}>
<h2>Interactive JSON Data</h2>
<JsonEditor
data={jsonData}
setData={handleDataChange}
restrictAdd={(path, value) => path.length < 3} // Example: only allow adding at root or first level
restrictDelete={(path) => path[0] !== 'products'} // Example: prevent deleting top-level 'products'
rootName="MyAppData"
theme={darkTheme}
highlightUpdates={true}
showArrayIndices={true}
showObjectSize={true}
/>
<pre style={{ marginTop: '20px', backgroundColor: '#eee', padding: '10px', borderRadius: '4px' }}>
<code>{JSON.stringify(jsonData, null, 2)}</code>
</pre>
</div>
);
}
export default MyJsonEditorComponent;