DEV Community


Posted on

Unexpected Behavior of React DOM Modification

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.

  1. Upon split: set the splitted node as the left child of a new parent node. Example - split(1)
  2. Upon remove: find the node's parent and replace it with node's sibling subtree. Example - remove(3)

Implementation details:

Node class

Represents the structure of the tree and supports:

  • split()
  • remove()
let id = 0

class Node {
  constructor(parent, children){ = id++
    this.children = children? children : null
    this.parent = parent? parent : null

    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

    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
Enter fullscreen mode Exit fullscreen mode


Recursive component which contains node as a state
and renders the node's subtree.

function TreeNode(props) {
  const [node, setNode] = useState(props.node)

  useEffect(() => {
    return () => {  
  }, [props.node]);

  const onRemove = () => {
      const newNode = node.remove()

  const onSplit = () => {

  return (
            <TreeNode node={node.children[0]} onRemove={setNode}/>
            <TreeNode node={node.children[1]} onRemove={setNode}/>
          <button onClick={onRemove}>remove</button>
          <button onClick={onSplit}>split</button>

Enter fullscreen mode Exit fullscreen mode

The problem

Consider the tree I showed above (example - remove(3)), the actual result is:
Actual result - remove(3)

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:
Actual result - remove(1)

Here is a full example in Sandbox:

Thanks in advance 🙏

Top comments (1)

wclayferguson profile image
Clay Ferguson

Your onRemove never updates the state right? Also useEffect normally should be using an existing state and not setting state.