Hello developers π
I need help in understanding a piece of code that I developed recently.
My goal is to display a full binary tree (0 or 2 children allowed) which gives the user the ability to interact only with the leaves. The user can either split or remove a specific leaf.
- Upon split: set the splitted node as the left child of a new parent node.
- Upon remove: find the node's parent and replace it with node's sibling subtree.
Implementation details:
Node class
Represents the structure of the tree and supports:
- split()
- remove()
let id = 0 class Node { constructor(parent, children){ this.id = id++ this.children = children? children : null this.parent = parent? parent : null } split(){ const node = new Node(this.parent) node.children = [this, new Node(node)] this.parent = node if (node.parent) { // Replace parent's child (this) with node } return node } remove(){ const parent = this.parent if (!parent) { return this } const sibling = parent.children.find((child) => child !== this) sibling.parent = parent.parent if (parent.parent) { // Replace grandparent's child (this.parent) with sibling } return sibling } }
TreeNode
Recursive component which contains node as a state
and renders the node's subtree.
function TreeNode(props) { const [node, setNode] = useState(props.node) useEffect(() => { setNode(props.node) return () => { }; }, [props.node]); const onRemove = () => { const newNode = node.remove() props.onRemove(newNode) } const onSplit = () => { setNode(node.split()) } return ( <div> { node.children? <div> <label>{node.id}</label> <div> <TreeNode node={node.children[0]} onRemove={setNode}/> <TreeNode node={node.children[1]} onRemove={setNode}/> </div> </div>: <div> <button onClick={onRemove}>remove</button> <button onClick={onSplit}>split</button> <label>{node.id}</label> </div> } </div> ) }
The problem
Consider the tree I showed above (example - remove(3)), the actual result is:
Although the tree structure is correct.
So here is my question - why React doesn't change the DOM as I expected (as I showed in the above)?
I also noticed that React does change the DOM as I expected for this case:
Here is a full example in Sandbox: https://codesandbox.io/embed/full-binary-tree-react-21r77
Thanks in advance π
Top comments (1)
Your onRemove never updates the state right? Also useEffect normally should be using an existing state and not setting state.