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

How do you implement controlled select? #243

Open
hyperknot opened this issue Apr 12, 2024 · 6 comments
Open

How do you implement controlled select? #243

hyperknot opened this issue Apr 12, 2024 · 6 comments

Comments

@hyperknot
Copy link

I'm using this in a controlled way. My problem is that it seems it's not possible to do a controlled select.

I mean the whole component is controlled, but select is going through a spaghetti (in my case) of onSelect + treeAPI.deselectAll() + treeApi.selectMulti().

But then it can get in an infinite loop, with a selectMulti triggering onSelect, etc. triggering selectMulti, etc.

Normally in React these are solved by controlled components. In Arborist's case, it'd be something like a selectedMap={} property, which takes a Map of selected id and selects them.

How do you solve this problem?

@Pancham97
Copy link

Okay, so I got around this with a little hack if you will.
I overrode the props of the Node and passed a locally maintained state to the checkbox.

<Tree
  ref={treeRef}
  data={data}
  disableDrag
  disableMultiSelection={false}
  className="selection-tree"
  onSelect={handleSelect}
>
  {(props) => <Node isSelected={isSelected} setIsSelected={setIsSelected} {...props} />}
</Tree>

@hyperknot
Copy link
Author

hyperknot commented May 29, 2024 via email

@Joshlha
Copy link

Joshlha commented Jul 23, 2024

@Pancham97 Can you give a little more detail on this? Been struggling with implementing a solution for a bit now.

I'm not sure why you're passing in setIsSelected as props. Where is that coming from? Is it a function that exists in your outer react component (outside of the tree?)

Thanks

@Pancham97
Copy link

@Pancham97 Can you give a little more detail on this? Been struggling with implementing a solution for a bit now.

I'm not sure why you're passing in setIsSelected as props. Where is that coming from? Is it a function that exists in your outer react component (outside of the tree?)

Thanks

@Joshlha yeah pretty much. Since React Arborist wouldn't maintain the state of selection, I made my own state using useState and pass the state and the setter as props. Whenever the checkbox is selected, it calls the setState method. I could whip up a small code gist if you want.

@Joshlha
Copy link

Joshlha commented Jul 24, 2024

@Pancham97 I think I get what you're saying. I would imagine that isSelected holds the state of all nodes? And the set function sets the state of a particular node.

A code sample would be extremely helpful! I've been fighting with the built-in selection management provided by the tree and it's just not very flexible.

@Pancham97
Copy link

@Joshlha I agree.

Here's something that I might have done. I do not have the exact piece of code because I didn't think this was an elegant use of a tree. For my use-case, I went with the standard accordions since that fit my need better.

function Node({ isSelected, setIsSelected, ...props }) {
  return (
    <input
      type="checkbox"
      checked={isSelected}
      onChange={() => setIsSelected(!isSelected)}
      {...props}
    />
  );
}

function Parent() {
  const [isSelected, setIsSelected] = React.useState(false);
  return (
    <Tree
      ref={treeRef}
      data={data}
      disableDrag
      disableMultiSelection={false}
      className="selection-tree"
      onSelect={handleSelect}
    >
      {(props) => (
        <Node
          isSelected={isSelected}
          setIsSelected={setIsSelected}
          {...props}
        />
      )}
    </Tree>
  );
}

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