--- title: Expandable object tree view type: snippet tags: [components,object,state,recursion] author: chalarangelo cover: digital-nomad-9 dateModified: 2020-11-16T16:50:57+02:00 --- Renders a tree view of a JSON object or array with collapsible content. - Use the value of the `toggled` prop to determine the initial state of the content (collapsed/expanded). - Use the `useState()` hook to create the `isToggled` state variable and give it the value of the `toggled` prop initially. - Render a `` element and bind its `onClick` event to alter the component's `isToggled` state. - Determine the appearance of the component, based on `isParentToggled`, `isToggled`, `name` and checking for `Array.isArray()` on `data`. - For each child in `data`, determine if it is an object or array and recursively render a sub-tree or a text element with the appropriate style. ```css .tree-element { margin: 0 0 0 4px; position: relative; } .tree-element.is-child { margin-left: 16px; } div.tree-element::before { content: ''; position: absolute; top: 24px; left: 1px; height: calc(100% - 48px); border-left: 1px solid gray; } p.tree-element { margin-left: 16px; } .toggler { position: absolute; top: 10px; left: 0px; width: 0; height: 0; border-top: 4px solid transparent; border-bottom: 4px solid transparent; border-left: 5px solid gray; cursor: pointer; } .toggler.closed { transform: rotate(90deg); } .collapsed { display: none; } ``` ```jsx const TreeView = ({ data, toggled = true, name = null, isLast = true, isChildElement = false, isParentToggled = true }) => { const [isToggled, setIsToggled] = React.useState(toggled); const isDataArray = Array.isArray(data); return (
setIsToggled(!isToggled)} /> {name ?   {name}: :   } {isDataArray ? '[' : '{'} {!isToggled && '...'} {Object.keys(data).map((v, i, a) => typeof data[v] === 'object' ? ( ) : (

{isDataArray ? '' : {v}: } {data[v]} {i === a.length - 1 ? '' : ','}

) )} {isDataArray ? ']' : '}'} {!isLast ? ',' : ''}
); }; ``` ```jsx const data = { lorem: { ipsum: 'dolor sit', amet: { consectetur: 'adipiscing', elit: [ 'duis', 'vitae', { semper: 'orci' }, { est: 'sed ornare' }, 'etiam', ['laoreet', 'tincidunt'], ['vestibulum', 'ante'] ] }, ipsum: 'primis' } }; ReactDOM.createRoot(document.getElementById('root')).render( ); ```