Interactive React Tree View Component
Building a tree view component is a common requirement in many applications, from file explorers to organizational charts. This challenge asks you to implement a React component that displays a hierarchical data structure as a tree, allowing users to expand and collapse nodes. This component will be useful for visualizing and interacting with nested data in a user-friendly way.
Problem Description
You are tasked with creating a TreeView component in React using TypeScript. The component should accept a data structure representing a tree as a prop. Each node in the tree will have a name property (string) and an optional children property (an array of child nodes, each with the same structure). The component should render the tree visually, with each node displaying its name. Nodes with children should be expandable/collapsible. Clicking on a node with children should toggle its expanded state.
Key Requirements:
- Data Structure: The component should accept a tree data structure as a prop.
- Rendering: Each node should be rendered with its
name. - Expand/Collapse: Nodes with children should have an indicator (e.g., a plus/minus icon) to show their expanded/collapsed state. Clicking the indicator should toggle the expanded state.
- Recursive Rendering: The component should recursively render the children of each node.
- Visual Indication: Visually differentiate between expanded and collapsed nodes (e.g., using different icons or indentation).
- TypeScript: The component must be written in TypeScript.
Expected Behavior:
- Initially, all nodes with children should be collapsed.
- Clicking a node's expand/collapse indicator should toggle the visibility of its children.
- The tree should be rendered correctly regardless of the depth of the tree.
- The component should handle empty child arrays gracefully (no errors, no visual artifacts).
Edge Cases to Consider:
- Empty tree (root node with no children).
- Nodes with no children.
- Deeply nested trees (performance considerations - although optimization is not the primary focus for this challenge).
- Data structure with missing
nameproperty (handle gracefully, perhaps displaying a default name).
Examples
Example 1:
Input:
const treeData = [
{
name: 'Root',
children: [
{ name: 'Child 1' },
{
name: 'Child 2',
children: [
{ name: 'Grandchild 1' },
{ name: 'Grandchild 2' },
],
},
],
},
];
Output:
(A tree view where 'Root' is initially collapsed, and when expanded shows 'Child 1' and 'Child 2'. 'Child 2' is initially collapsed, and when expanded shows 'Grandchild 1' and 'Grandchild 2'.)
Explanation: The component recursively renders the tree structure, displaying each node's name and providing expand/collapse functionality for nodes with children.
Example 2:
Input:
const treeData = [
{ name: 'Root' },
{
name: 'Child 1',
children: [],
},
];
Output:
(A tree view where 'Root' and 'Child 1' are both displayed and are not expandable because they have no children.)
Explanation: Nodes without children are rendered as leaf nodes without expand/collapse indicators.
Example 3: (Edge Case)
Input:
const treeData = [];
Output:
(An empty tree view - nothing is rendered.)
Explanation: The component handles the case where the input tree data is empty.
Constraints
- Component Structure: The component should be a functional component using React Hooks.
- Data Type: The
treeDataprop should be an array of objects, where each object represents a node and has at least anameproperty (string). Thechildrenproperty, if present, should be an array of the same type. - Performance: While optimization is not the primary focus, avoid unnecessary re-renders. Simple memoization techniques are acceptable.
- Styling: Basic styling is acceptable (e.g., indentation, icons). Complex styling is not required. Use inline styles or a simple CSS file.
Notes
- Consider using recursion to traverse the tree structure.
- Maintain the expanded/collapsed state of each node using component state.
- Think about how to efficiently update the UI when a node's expanded state changes.
- You can use any React libraries you are comfortable with, but keep the solution relatively simple. Avoid complex state management libraries like Redux for this challenge.
- Focus on the core functionality of rendering the tree and handling expand/collapse actions.