Rendering React components (or similar) in Decoration.toDOM()?

Hi, I’m working on an editor that replaces certain AST nodes with interactive components when possible. Similar to the true/false checkbox example, but extended to things like augmenting [r, g, b] or [h, s, l] with a RGB or HSL color picker.

In my app, an React component renders the Codemirror editor and maintains a ref to its view. Is it possible to somehow return a React component in the toDOM method of a Decoration, or replace toDOM with something else capable of rendering a React component in the same tree as the Editor component?

I would like to render Decorations using React because it most closely matches how I build UI throughout the rest of my app, and would allow me to use the same components (e.g. color picker) in the editor and in an exported “view mode”. Otherwise, I would need to rewrite the rendering code for things like the color picker to be vanilla, which I would prefer not to do.

Thank you!

I generally recommend against this, since it introduces a bunch of extra indirection an inefficiency that, for all but the most complicated widgets, isn’t going to pay off, but I believe react has a feature called portals that may help with this—have the toDOM method return a parent node, and then asynchronously wire it up to a react portal.

3 Likes

Using the element returned from toDOM as a portal container did not work for me. Anything that I attach to the container element from my React code gets deleted.

you can do something like this to render react component inside a dom element then return the dom element

const dom = document.createElement('div')
  const root = ReactDOM.createRoot(dom)
  root.render(
    <Reactcomponent />
  )
  return { dom }