Replace findDOMNode with a ref to support React 19 - #1050
Conversation
React 19 removed findDOMNode, which getEditingArea() relied on to resolve the editing area to a DOM node. Capture the element with a ref instead and read it directly. The library no longer imports react-dom. Adds ^19 to the react and react-dom peer ranges, and tests covering the default editing area, a custom one passed via children, and re-resolution after regeneration.
42caa31 to
1d3aa37
Compare
|
Same issue. Hope to get this merged soon for React 19 support |
|
For what it's worth, the branch is still current — Being straight about the odds, though: the last push to this repository was 2025-02-22, and there are 433 open issues. I opened #1051 offering to help with triage or maintenance if the maintainers want it, and there has been no reply. So I would not plan around this merging soon. If you need React 19 working today rather than waiting, |
Summary
getEditingArea()is the only place in the codebase that callsReactDOM.findDOMNode. React 19 removed that API, so the component throwsTypeError: findDOMNode is not a functionon mount and the package is unusable there. This replaces it with a plain ref.Fixes #972, #981, #1034, #1039. Also relevant to #988, #989, #1022, #1032.
What changed
The editing area used to be captured with a callback ref typed as
React.ReactInstance, which may be a class instance rather than a DOM node — hence thefindDOMNodecall to unwrap it. Switching toReact.createRef()gives the DOM node directly and the unwrapping step disappears.src/index.tsx— dropped thereact-domimport, replacededitingAreawitheditingAreaRef, read.currentingetEditingArea()package.json— added^19to thereactandreact-dompeer rangestest/index.js— three tests covering the default editing area, a custom one passed viachildren, and re-resolution after the editor regeneratesThe library no longer imports
react-domat all. I left it inpeerDependenciessince consumers still need it and removing it would change dependency resolution for no real benefit, but I'm happy to drop it if you'd rather.Behaviour change
Worth calling out:
findDOMNodeused to resolve a class component down to its DOM node. Without it, if someone passeschildrenthat is a class component instead of a host element,ref.currentis the component instance and not a DOM node.The README documents
childrenas a custom editing area element, so I expect this to be rare in practice, but it is technically a breaking change. I added an explicitinstanceof Elementcheck so anyone hitting it gets a clear message instead of a confusing Quill error. Let me know if you'd prefer this to land as a major, or if you want the old behaviour preserved behind a fallback.Testing
npm run build:libpasses clean under the existingtscconfig. The mocha suite passes 17/17 locally — note it needs--exiton modern Node, since mocha 6 plus jsdom leaves the process hanging otherwise. That's unrelated to this change and I left it alone.I haven't touched the Quill v1 dependency. Upgrading to Quill 2 means rewriting the type layer, since
QuillOptionsStatic,DeltaStaticand friends come from@types/quilland don't exist in Quill 2 — that seemed worth keeping separate from this fix. Happy to open that as a follow-up if it's useful.