What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
A small React tree view can be built from recursive data and a recursive component: give every node a stable ID and label, store expanded IDs in state, and render children only when their parent is open. If the result is an interactive tree widget—not just nested content—you must also implement its keyboard and focus behavior, not merely add ARIA roles.
Choose nested content or an interactive tree widget
First decide what users need to do. If the interface is simply a hierarchy of links or text, nested semantic lists may be a better fit than a composite tree widget with custom keyboard navigation. The WAI-ARIA tree pattern is intended for a widget with tree-style focus and interaction; its roles alone do not supply that behavior.
For a widget, plan for arrow-key navigation, opening and closing parent nodes, focus management, and any selection behavior. The W3C tree-view pattern describes the expected interaction and states.
Model nodes with stable IDs
Use a recursive data shape with an ID, a display label, and optional children. Stable IDs serve both as React keys and as references in expansion or selection state; array indexes are unsuitable identities when nodes can move or change.
#1 Best Overall
const nodes = [
{
id: "src",
label: "src",
children: [
{ id: "app", label: "App.jsx" },
{ id: "components", label: "components", children: [
{ id: "tree-view", label: "TreeView.jsx" }
] }
]
},
{ id: "readme", label: "README.md" }
];
A node with a nonempty children array is a parent; a node without children is a leaf. Keep selection state separate from expansion state: opening a folder does not necessarily mean the user selected it.
Render a simple collapsible nested list
For a small tree that does not need the full tree-widget keyboard model, recursive nested lists are straightforward and preserve familiar list semantics. This example keeps expanded IDs locally and uses a button for disclosure. The button and label are distinct so a future link or selection action can be added without conflating it with expansion.
import { useState } from "react";
function Tree({ nodes }) {
const [expandedIds, setExpandedIds] = useState(() => new Set());
function toggle(id) {
setExpandedIds(current => {
const next = new Set(current);
if (next.has(id)) next.delete(id);
else next.add(id);
return next;
});
}
return (
<ul>
{nodes.map(node => {
const hasChildren = Boolean(node.children?.length);
const expanded = expandedIds.has(node.id);
return (
<li key={node.id}>
{hasChildren && (
<button
type="button"
aria-expanded={expanded}
onClick={() => toggle(node.id)}
>
{expanded ? "Collapse" : "Expand"} {node.label}
</button>
)}
<span>{node.label}</span>
{hasChildren && expanded && (
<Tree nodes={node.children} />
)}
</li>
);
})}
</ul>
);
}
This version intentionally renders ordinary nested lists rather than claiming to implement the ARIA tree pattern. For a production tree widget, do not treat the example as complete: implement the required focus model and keyboard interactions, and expose state according to the widget pattern.
Implement the tree pattern when the interface needs it
A tree widget needs an accessible name, parent expansion state, appropriate selection state, and keyboard behavior. The W3C pattern specifies that parent items expose aria-expanded according to whether they are open; leaves should not expose that state. Give the tree a visible label referenced by aria-labelledby, or another suitable accessible name such as aria-label.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Rank #3
- Support the pattern’s arrow-key movement and opening or closing of parent nodes.
- Represent selection only for nodes that are selectable. Focus and selection are separate concepts and may not move together.
- Test the empty tree, a leaf, a parent, disabled nodes if supported, and the difference between focused and selected items.
- Check keyboard-only use and screen-reader output in the browsers and assistive technologies your application supports.
If selecting or unselecting every node is an important task, W3C recommends separate “Select All” and “Unselect All” controls rather than relying on tree-item interaction alone.
When to use a library instead
Hand-building is reasonable when the data and interactions are small and well defined. A library becomes more useful when you need a complete keyboard model, selection modes, dynamic data, or advanced operations. MUI X distinguishes its components by use case; its documentation recommends SimpleTreeView for items expressed as JSX children and RichTreeView for dynamically supplied data, larger trees, or more advanced needs.
Rank #4
| Option | Documented fit | Considerations |
|---|---|---|
| Hand-built component | Small, specific interaction and data needs | You own keyboard behavior, accessibility states, testing, and maintenance. |
MUI X SimpleTreeView |
Items hardcoded as JSX children | Requires an accessible name; follow the MUI X quickstart for current setup and dependencies. |
MUI X RichTreeView |
Dynamic data, larger trees, or advanced needs | MUI X lists capabilities such as reordering, lazy loading, and virtualization among Pro features; its overview describes Community as MIT licensed and Pro as requiring a commercial license. See the MUI X tree-view overview. |
react-accessible-treeview |
An existing package whose npm listing describes single or multiple selection, disabled nodes, keyboard bindings, customization, and TypeScript declarations | The listing shows version 2.11.2 and says the project is seeking new maintainers. Check the current npm listing before adopting it. |
MUI’s item guidance requires each item to have a unique itemId and a label; see its Simple Tree View items documentation. A feature list is not a performance comparison: the cited material does not establish a universal data-size threshold or independent benchmark for choosing a component.
Test the component before shipping
For a simple nested list, verify that each disclosure button opens and closes only its own branch, nested children appear at the expected level, IDs remain stable when the data changes, and the control announces its expanded state.
Recommended Free Tools
Best Value
For a tree widget, also exercise every documented keyboard action without a mouse, verify the accessible name and announced item states, and ensure focus remains distinguishable from selection. Re-test after changing libraries or updating versions because APIs, dependencies, and maintenance status can change.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




