DEV Community

Justin Clark
Justin Clark

Posted on

Building Tree Views with react-treeview in React

react-treeview is a simple and lightweight React component for creating tree views with expandable and collapsible nodes. It provides an easy-to-use API for displaying hierarchical data structures like file systems, directory trees, and nested menus. This guide walks through setting up and creating tree views using react-treeview with React, from installation to a working implementation.

Prerequisites

Before you begin, make sure you have:

  • Node.js version 14.0 or higher installed
  • npm, yarn, or pnpm package manager
  • A React project (version 16.8 or higher) or create-react-app setup
  • Basic knowledge of React hooks (useState)
  • Familiarity with JavaScript/TypeScript
  • Understanding of tree data structures

Installation

Install react-treeview using your preferred package manager:

npm install react-treeview
Enter fullscreen mode Exit fullscreen mode

Or with yarn:

yarn add react-treeview
Enter fullscreen mode Exit fullscreen mode

Or with pnpm:

pnpm add react-treeview
Enter fullscreen mode Exit fullscreen mode

After installation, your package.json should include:

{
  "dependencies": {
    "react-treeview": "^0.4.0",
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

Project Setup

react-treeview requires minimal setup. Import the TreeView component and provide tree data.

First Example / Basic Usage

Let's create a simple tree view. Create a new file src/TreeViewExample.jsx:

// src/TreeViewExample.jsx
import React from 'react';
import TreeView from 'react-treeview';

const treeData = {
  label: 'Root',
  collapsed: false,
  children: [
    {
      label: 'Child 1',
      collapsed: false,
      children: [
        { label: 'Grandchild 1' },
        { label: 'Grandchild 2' }
      ]
    },
    {
      label: 'Child 2',
      collapsed: true,
      children: [
        { label: 'Grandchild 3' }
      ]
    },
    { label: 'Child 3' }
  ]
};

function TreeViewExample() {
  const [data, setData] = React.useState(treeData);

  const handleClick = (node) => {
    node.collapsed = !node.collapsed;
    setData({ ...data });
  };

  return (
    <div style={{ padding: '20px', maxWidth: '400px' }}>
      <h2>Basic Tree View Example</h2>
      <div style={{ border: '1px solid #ddd', borderRadius: '4px', padding: '10px' }}>
        <TreeView
          data={data}
          onClick={handleClick}
        />
      </div>
    </div>
  );
}

export default TreeViewExample;
Enter fullscreen mode Exit fullscreen mode

Update your App.jsx:

// src/App.jsx
import React from 'react';
import TreeViewExample from './TreeViewExample';
import './App.css';

function App() {
  return (
    <div className="App">
      <TreeViewExample />
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

This creates a basic tree view with expandable and collapsible nodes.

Understanding the Basics

react-treeview provides tree view components:

  • TreeView: Main tree component
  • Node structure: Each node has label and optional children and collapsed properties
  • Click handler: Handle node clicks to toggle expansion
  • Custom styling: Style nodes with CSS

Key concepts:

  • Tree data structure: Each node has label and optional children array
  • Collapsed state: Control node expansion with collapsed property
  • Click events: Use onClick to handle node interactions
  • Nested structure: Support for multiple levels of nesting

Here's an example with more features:

// src/AdvancedTreeViewExample.jsx
import React, { useState } from 'react';
import TreeView from 'react-treeview';

const advancedTreeData = {
  label: 'Documents',
  collapsed: false,
  children: [
    {
      label: 'Projects',
      collapsed: false,
      children: [
        { label: 'Project 1' },
        { label: 'Project 2' }
      ]
    },
    {
      label: 'Images',
      collapsed: true,
      children: [
        { label: 'Vacation' },
        { label: 'Family' }
      ]
    },
    { label: 'Downloads' }
  ]
};

function AdvancedTreeViewExample() {
  const [data, setData] = useState(advancedTreeData);
  const [selectedNode, setSelectedNode] = useState(null);

  const handleClick = (node) => {
    if (node.children) {
      node.collapsed = !node.collapsed;
      setData({ ...data });
    }
    setSelectedNode(node);
  };

  return (
    <div style={{ display: 'flex', padding: '20px' }}>
      <div style={{ width: '300px', border: '1px solid #ddd', borderRadius: '4px', padding: '10px' }}>
        <h3>File Tree</h3>
        <TreeView
          data={data}
          onClick={handleClick}
        />
      </div>
      <div style={{ flex: 1, marginLeft: '20px', padding: '20px', border: '1px solid #ddd', borderRadius: '4px' }}>
        <h3>Selected Node</h3>
        {selectedNode && (
          <div>
            <p><strong>Label:</strong> {selectedNode.label}</p>
            <p><strong>Has Children:</strong> {selectedNode.children ? 'Yes' : 'No'}</p>
            <p><strong>Collapsed:</strong> {selectedNode.collapsed ? 'Yes' : 'No'}</p>
          </div>
        )}
      </div>
    </div>
  );
}

export default AdvancedTreeViewExample;
Enter fullscreen mode Exit fullscreen mode

Practical Example / Building Something Real

Let's build a directory browser with file icons:

// src/DirectoryBrowser.jsx
import React, { useState } from 'react';
import TreeView from 'react-treeview';

const directoryData = {
  label: 'πŸ“ My Files',
  collapsed: false,
  children: [
    {
      label: 'πŸ“ Documents',
      collapsed: false,
      children: [
        { label: 'πŸ“„ Report.pdf' },
        { label: 'πŸ“„ Presentation.pptx' }
      ]
    },
    {
      label: 'πŸ“ Images',
      collapsed: false,
      children: [
        { label: 'πŸ–ΌοΈ photo1.jpg' },
        { label: 'πŸ–ΌοΈ photo2.png' }
      ]
    },
    {
      label: 'πŸ“ Downloads',
      collapsed: true,
      children: [
        { label: 'πŸ“„ file1.zip' }
      ]
    },
    { label: 'πŸ“„ readme.txt' }
  ]
};

function DirectoryBrowser() {
  const [data, setData] = useState(directoryData);
  const [selectedPath, setSelectedPath] = useState('');

  const handleClick = (node, path = '') => {
    const currentPath = path ? `${path} > ${node.label}` : node.label;

    if (node.children) {
      node.collapsed = !node.collapsed;
      setData({ ...data });
    }

    setSelectedPath(currentPath);
  };

  const renderTree = (node, path = '') => {
    return (
      <TreeView
        key={node.label}
        data={node}
        onClick={(n) => handleClick(n, path)}
      />
    );
  };

  return (
    <div style={{ padding: '20px', maxWidth: '600px' }}>
      <h2>Directory Browser</h2>
      <div style={{ border: '1px solid #ddd', borderRadius: '4px', padding: '10px', marginBottom: '20px' }}>
        <p><strong>Selected:</strong> {selectedPath || 'None'}</p>
      </div>
      <div style={{ border: '1px solid #ddd', borderRadius: '4px', padding: '10px' }}>
        {renderTree(data)}
      </div>
    </div>
  );
}

export default DirectoryBrowser;
Enter fullscreen mode Exit fullscreen mode

Now create a menu tree:

// src/MenuTree.jsx
import React, { useState } from 'react';
import TreeView from 'react-treeview';

const menuData = {
  label: 'Main Menu',
  collapsed: false,
  children: [
    {
      label: 'Home',
      collapsed: false
    },
    {
      label: 'Products',
      collapsed: false,
      children: [
        { label: 'Product 1' },
        { label: 'Product 2' },
        { label: 'Product 3' }
      ]
    },
    {
      label: 'Services',
      collapsed: true,
      children: [
        { label: 'Service 1' },
        { label: 'Service 2' }
      ]
    },
    { label: 'About' },
    { label: 'Contact' }
  ]
};

function MenuTree() {
  const [data, setData] = useState(menuData);

  const handleClick = (node) => {
    if (node.children) {
      node.collapsed = !node.collapsed;
      setData({ ...data });
    } else {
      console.log('Navigating to:', node.label);
    }
  };

  return (
    <div style={{ padding: '20px', maxWidth: '400px' }}>
      <h2>Navigation Menu</h2>
      <div style={{ border: '1px solid #ddd', borderRadius: '4px', padding: '10px' }}>
        <TreeView
          data={data}
          onClick={handleClick}
        />
      </div>
    </div>
  );
}

export default MenuTree;
Enter fullscreen mode Exit fullscreen mode

Update your App.jsx:

// src/App.jsx
import React from 'react';
import DirectoryBrowser from './DirectoryBrowser';
import MenuTree from './MenuTree';
import './App.css';

function App() {
  return (
    <div className="App">
      <DirectoryBrowser />
      <MenuTree />
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

This example demonstrates:

  • Directory browser interface
  • File and folder icons
  • Node selection
  • Path tracking
  • Menu navigation
  • Expandable nodes

Common Issues / Troubleshooting

  1. Tree not rendering: Make sure your data structure is correct. Each node needs a label property. Check that the root node is properly formatted.

  2. Nodes not expanding: Verify that nodes with children have a children array. Check that collapsed property is being toggled correctly.

  3. Click events not working: Ensure onClick handler is provided. Check that the handler updates the state to trigger re-render.

  4. Styling issues: react-treeview provides default styles. Override with custom CSS. Check that styles aren't being overridden by global CSS.

  5. Performance with large trees: For large trees, consider lazy loading children or virtualizing the tree. Limit the initial depth of expanded nodes.

  6. State management: Make sure to create a new object when updating state to trigger React re-renders. Use spread operator to create new state objects.

Next Steps

Now that you have an understanding of react-treeview:

  • Explore custom node rendering
  • Learn about styling options
  • Implement search and filtering
  • Add context menus
  • Create dynamic tree loading
  • Integrate with routing
  • Check the official repository: https://github.com/chenglou/react-treeview

Summary

You've successfully set up react-treeview in your React application and created tree views with expandable nodes, click handlers, and custom styling. react-treeview provides a simple solution for building hierarchical data displays in React applications.

SEO Keywords

react-treeview
react-treeview tree component
React tree view
react-treeview installation
React hierarchical data
react-treeview tutorial
React directory tree
react-treeview example
React expandable tree
react-treeview setup
React tree component library
react-treeview getting started
React nested tree
react-treeview advanced usage

Top comments (0)