Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uncontrolled tree state is not changed #244

Closed
bcburak opened this issue Mar 27, 2023 · 7 comments
Closed

Uncontrolled tree state is not changed #244

bcburak opened this issue Mar 27, 2023 · 7 comments
Assignees

Comments

@bcburak
Copy link

bcburak commented Mar 27, 2023

I'm trying to create a new node with the same level of tree structure. In React side it's all working with useState. I expect the existing tree will re-render and showed the updated "treeItems" state, however I can not see the tree nodes with updated tree state.
How should I add a new node with a specific properties I define?

Here is my tree and state code;

`const actualTree: ExactTree = {
  root: {
    index: "root",
    canMove: true,
    isFolder: true,
    children: ["Projects"],
    data: "root",
    canRename: true,
    countIndex: 2,
  },
  Projects: {
    index: "Projects",
    canMove: true,
    isFolder: true,
    children: ["GarbageCollector"],
    data: "Projects",
    canRename: true,
    countIndex: 2,
  },
  GarbageCollector: {
    index: "GarbageCollector",
    canMove: true,
    isFolder: true,
    children: ["Mas", "Blueberry"],
    data: "GarbageCollector",
    canRename: true,
    countIndex: 2,
  },
  Mas: {
    index: "Mas",
    canMove: true,
    isFolder: false,
    data: "Mas",
    canRename: true,
    countIndex: 2,
  },
  Blueberry: {
    index: "Blueberry",
    canMove: true,
    isFolder: false,
    data: "Blueberry",
    canRename: true,
    countIndex: 3,
  },
};`
` <UncontrolledTreeEnvironment<string>
            canDragAndDrop
            canDropOnFolder
            canReorderItems
            dataProvider={
              new StaticTreeDataProvider(
                treeItems as ExactTree,
                (item, data) => ({
                  ...item,
                  data,
                })
              )
            }
            getItemTitle={(item) => item.data}
            onFocusItem={(item) => setFocusedItem(item)}
            canRename={true}
            defaultInteractionMode={{
              mode: "custom",
              createInteractiveElementProps: (
                item,
                treeId,
                actions,
                renderFlags
              ) => ({
                onDoubleClick: (e) => {
                  e.preventDefault();
                  onTreeItemDoubleClick(e, item);
                },
                tabIndex: !renderFlags.isRenaming
                  ? renderFlags.isFocused
                    ? 0
                    : -1
                  : undefined,
              }),
            }}
            viewState={{
              "tree-1": {
                expandedItems: [],
              },
            }}
            {...bpRenderers}
          >
            <Tree treeId="tree-1" rootItem="root" treeLabel="Projects tree" />
          </UncontrolledTreeEnvironment>`
const addNewTreeNode = (nodeName: any) => {
       nodeName = "Environment";

    const treeNode = {
      index: nodeName,
      canMove: true,
      isFolder: false,
      data: nodeName,
      canRename: true,
      countIndex: 2,
    };

    actualTree[nodeName] = treeNode;
    // const jsonArray = JSON.stringify([actualTree]);
  
    setTreeItems(actualTree);
    console.log("setted", treeItems);
  };
@lukasbach
Copy link
Owner

If you want to react to tree state changes, I suggest you implement a custom TreeDataProvider rather than using StaticTreeDataProvider. There you can implement logic that reacts to change events. If you need more control, you can also use a controlled environment rather than an uncontrolled environment, then you get complete control over your data.

@mikebridge
Copy link

@lukasbach It's not clear to me how to rerender the tree with fresh data from the TreeDataProvider interface---if I add a new node, delete a node, or want to refresh the data completely, do I need to emit an event somehow? It's not clear to me how my custom TreeDataProvider needs to communicate changes to the tree.

@mikebridge
Copy link

mikebridge commented Jan 19, 2024

Yeah, I can update the data in the provider but I can't see how to get the tree to see it (except when renaming).

I tried setting the new data then calling this.onDidChangeTreeDataEmitter.emit(Object.keys(this.data.items)) thinking that would maybe refresh the entire tree and that maybe something was listening. That did nothing.

I also tried recreating the provider entirely. It doesn't seem to see the change. I'm sure there's something easy here but I can't figure it out.

@mikebridge
Copy link

Also did not work:

  • calling onChangeItemChildren, adding the new id as a child of the root element.

@lukasbach
Copy link
Owner

@mikebridge are you using a custom data provider, or static tree data provider? With the latter, calling onDidChangeTreeDataEmitter with affected, or all, tree ids should work. In case of a custom provider, you need to make sure to propagate the changes to all listeners registered through onDidChangeTreeData.

I just expanded the docs on static data providers and on custom data providers. Maybe you can find something helpful there.

If not, can you open an issue for your problem and share your code there? I would need to see the implementation to see what's going wrong.

@mikebridge
Copy link

@mikebridge are you using a custom data provider, or static tree data provider? With the latter, calling onDidChangeTreeDataEmitter with affected, or all, tree ids should work. In case of a custom provider, you need to make sure to propagate the changes to all listeners registered through onDidChangeTreeData.

I just expanded the docs on static data providers and on custom data providers. Maybe you can find something helpful there.

If not, can you open an issue for your problem and share your code there? I would need to see the implementation to see what's going wrong.

Thanks! I was able to get this to work based on your updated examples---the issue was mainly to do with knowing what events to emit. I will clean my code up and post it when I have a few minutes.

(I was working with a custom provider which was basically the static data provider.)

@lukasbach
Copy link
Owner

Happy to hear! Yes the docs were lacking before on that topic, I hope now it's clearer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants