S
SolidJS•13mo ago
lars

updating a tree of nodes in a SolidJS store

hey y'all. i'm trying to build a tree view where nodes have an isExpanded state i'm having a tough time trying to update the corresponding node. below is the approach i've tried but it doesn't trigger a component update for whatever reason. if there's a totally different way to do this, then i'm all ears
type Node = {
id: string;
isExpanded: boolean;
children: Node[];
}

export function useTreeState() {
const [treeState, setTreeState] = createStore<Node[]>([]);

function setNodeExpansion(id: string, isExpanded: boolean): void {
setTreeState(
produce(tree => {
// Traverse down to get the node to update.
const foundNode = getNodeDeep(styleTree, id);
foundNode.isExpanded = true; // <---- this doesn't actually update
return tree;
}),
);
}
}
type Node = {
id: string;
isExpanded: boolean;
children: Node[];
}

export function useTreeState() {
const [treeState, setTreeState] = createStore<Node[]>([]);

function setNodeExpansion(id: string, isExpanded: boolean): void {
setTreeState(
produce(tree => {
// Traverse down to get the node to update.
const foundNode = getNodeDeep(styleTree, id);
foundNode.isExpanded = true; // <---- this doesn't actually update
return tree;
}),
);
}
}
2 Replies
thetarnav
thetarnav•13mo ago
a deeply nested tree structure is probably better handled by createMutable, just using signals with classes, or utilising this trick: https://github.com/solidjs/solid/issues/1300 But if you want to do it the way you do this - by reconstructing the path to the node, it's possible too, and should work if you get the path right. It should work. So I suspect that getNodeDeep is not doing the right job. Like, why are you passing styleTree there, and not tree - a writable proxy that you get from produce? Also why are you returning tree from produce? I don't think it does anything. Also It's a common technique to extract states such as active and collapsed from the data structure to a separate set. As usually whether a node is collapsed or not and only view-related concern, you can leave your data structure out of that. This is what I use in the devtools: https://github.com/thetarnav/solid-devtools/blob/main/packages/frontend/src/modules/structure/Structure.tsx#L177-L183
lars
lars•13mo ago
wow, thank you for such a detailed response 🙌 🙌 i'll have a look through your links