Skip to content

Runtime error in useTreeData example. #1940

Closed
@onelson

Description

@onelson

🙋 Documentation Request

The existing useTreeData example doesn't seem to run without error, and certainly doesn't type-check well when written in Typescript instead of JS.

Here's the traceback I see when I follow along with the docs:

TypeError: Cannot read property 'map' of undefined
    at buildTree (module.js:559)
    at module.js:566
    at Array.map (<anonymous>)
    at buildTree (module.js:559)
    at module.js:566
    at Array.map (<anonymous>)
    at buildTree (module.js:559)
    at module.js:554
    at updateMemo (react-dom.development.js:15867)
    at Object.useMemo (react-dom.development.js:16413)
    at useMemo (react.development.js:1532)
    at useTreeData (module.js:554)

Here's a slightly modified version of what's in the docs today, rephrased to use TS and to be self-contained/complete.

import React from "react";
import {
  ListBox,
  Section,
  Item,
  useTreeData,
  Provider as ThemeProvider,
  defaultTheme,
} from "@adobe/react-spectrum";

interface Node {
  name: string;
  items?: Node[];
}

export function MyTreeList() {
  const tree = useTreeData<Node>({
    initialItems: [
      {
        name: "People",
        items: [{ name: "David" }, { name: "Sam" }, { name: "Jane" }],
      },
      {
        name: "Animals",
        items: [{ name: "Aardvark" }, { name: "Kangaroo" }, { name: "Snake" }],
      },
    ],
    initialSelectedKeys: ["Sam", "Kangaroo"],
    getKey: (item) => item.name,
    getChildren: (item) =>
      // XXX: Fallback to empty array required to avoid invalid
      // `.map()` on `undefined`. Can fix by rewriting: `item.items || []`
      item.items,
  });

  return (
    <ThemeProvider theme={defaultTheme}>
      <ListBox
        items={tree.items}
        selectedKeys={tree.selectedKeys}
        // XXX: Type mismatch for the onSelectionChange prop.
        onSelectionChange={tree.setSelectedKeys}
      >
        {(node) => (
          <Section title={node.value.name} items={node.children}>
            {(node) => <Item>{node.value.name}</Item>}
          </Section>
        )}
      </ListBox>
    </ThemeProvider>
  );
}

I think the dealbreaker docs-wise is the runtime error caused by the current implementation shown for getChildren().


Since the docs are not expressly written using TS, I'm not sure how the onSelectionChange issue fits into the scheme of things but here's the gap:

TS2322: Type '(keys: Set<Key>) => void' is not assignable to type '(keys: Selection) => any'.   Types of parameters 'keys' and 'keys' are incompatible.     Type 'Selection' is not assignable to type 'Set<Key>'.       Type 'string' is not assignable to type 'Set<Key>'.

I guess, separately, just know that TS users will have to strong-arm the type inference using as to get the example to work written as it is today.

🧢 Your Company/Team

N/A

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions