pomber / didact

A DIY guide to build your own React
https://pomb.us/build-your-own-react/
6.29k stars 531 forks source link

"DELETION" exception #30

Open WangYuLue opened 3 years ago

WangYuLue commented 3 years ago

In commitWork function, when entering DELETION condition judgment,it should ruturn

    )
  } else if (fiber.effectTag === "DELETION") {
    domParent.removeChild(fiber.dom)
+   return
  }

  commitWork(fiber.child)
  commitWork(fiber.sibling)
}

Otherwise didact will repeatedly delete child elements, and will throw a exception:

屏幕快照 2020-10-28 下午8 18 40

Here is my test code

/** @jsx Didact.createElement */
const container = document.getElementById("root")

const updateValue = e => {
  rerender(e.target.value)
}

const rerender = value => {
  const element = (
    <div>
      <input onInput={updateValue} value={value} />
      <h2>Hello {value}</h2>
      {
        value === '1' ? <div><span>a</span><span>b</span></div> : <div><div>c</div><div>d</div></div>
      }
    </div>
  )
  Didact.render(element, container)
}

rerender("World")

The operation effect is as follows:

ezgif com-gif-maker (1)

Test it on codesandbox

I open a PR to fix the question

kusamochi commented 3 years ago

hi there, I came across the same problem, I found out the node may have been already removed before commitDeletion (I guess it is because of the way non-blocking works), therefore parentNode is null. I just changed domParent.removeChild(fiber.dom); to fiber.dom.remove();