1

How to remove this error message from my console

enter image description here

I'm using ReactDOM.render to replace certain "unreachable" parts of my code with JSX components, it worked fine in previous versions but now I'm getting this annoying error message and I want to get rid of it.

Long story:

I'm using the FullCalendar lib for react18 and Nextjs.

I'm facing a limitation from the lib, in previous versions I was able to pass JSX to render in the header buttons, but in the current version 5.11.2 it's not possible anymore, it only let you set either text or a bootstrap/font-awesome icon.

So I instead used an old known trick to replace DOM with no more than the HTML element

ReactDOM.render(
  <AnyIconIWantToUse />,
  window.document.querySelector("#element-to-replace-id")
)

and that is what brings up the said error message

What I've tried

As the error suggest I've tried using createRoot instead but it gives me an error too (and afaik it's meant to be used only with the root component so I prefer not to use it).

HYAR7E
  • 194
  • 2
  • 10
  • You could try rendering a React Portal: https://reactjs.org/docs/portals.html – Nils Hartmann Aug 27 '22 at 07:34
  • 1
    Does this answer your question? [Deprecation notice: ReactDOM.render is no longer supported in React 18](https://stackoverflow.com/questions/71668256/deprecation-notice-reactdom-render-is-no-longer-supported-in-react-18) – Youssouf Oumar Aug 27 '22 at 10:32

2 Answers2

1

This should help you out

createPortal(
    <AnyIconIWantToUse />,
    document.getElementById("element-to-replace-id")
 )
  • Thanks for your answer, I tried it but couldn't get it working, portals won't allow me to change the main root DOM (my code) and most implementations of Portals I've seen do that same thing, it doesn't replace the DOM but creates a new root outside – HYAR7E Aug 27 '22 at 22:47
0

I ended up achieving what I wanted with another approach.

Instead of replacing DOM content directly with JSX I instead render the desired JSX into the DOM and replace the DOM with DOM

// utils/replaceDOM.ts
import type React from 'react';
import { renderToString } from 'react-dom/server';

type ReplaceDOM = (
  elementToReplace: Element,
  replacement: React.ReactElement
) => void;

const replaceDOM: ReplaceDOM = (elementToReplace, replacement) => {
  if (!replacement) return;
  // Get html from component (only get first render)
  const replacementHTML = renderToString(replacement);
  // Parse html string into html
  const parser = new DOMParser();
  const parsedDocument = parser.parseFromString(replacementHTML, 'text/html');
  const replacementElement = parsedDocument.body.children[0];
  // Append replacement to DOM
  window.document.body.prepend(replacementElement);
  // Replace children with element
  elementToReplace.replaceWith(replacementElement);
};

export default replaceDOM;

Then I can use it as desired

replaceDOM(elementToReplace, <ElementIWant className="w-6" />);
HYAR7E
  • 194
  • 2
  • 10