skip to Main Content

Given a HTMLElement ref created by React.useRef(), is it possible to render a new Component inside of it?

For example:

const DemoComponent: React.FunctionComponent = () => {
  const ref = React.useRef<HTMLElement>(null);

  useRenderExample(ref);

  return (
    <>
      <div ref={ref}>RENDER_PLACEHOLDER</div>
      <div>Some other elements and components...</div>
    </>
  );
}

function useRenderExample(ref: React.RefObject<HTMLElement>) {
  const element = ref.corrent;
  if (element) {
    // 1. This will work:
    element.innerHTML = 'Hello World';

    // 2. This will NOT work (innerHTML except string only):
    // h1 is just an example, I would like to have here
    // a more complex FunctionComponent
    element.innerHTML = <h1>HELLO</h1>;
  }
}

2

Answers


  1. Chosen as BEST ANSWER

    After some investigation I found the ReactDOM package - that you are probably already using for rendering your entire application (unless you are using different render engine like ReactNative, ReactVR, etc...).

    The ReactDOM come with a few render methods, the one I found useful is ReactDOM.render(componentToRender, containerElement);

    To solve my issue I used:

    import ReactDOM from 'react-dom';
    
    function useRenderExample(ref: React.RefObject<HTMLElement>) {
      const container = ref.corrent;
      if (container) {
        ReactDOM.render(<h1>Hello World</h1>, container);
      }
    }
    

    You should also look at ReactDOM.createPortal(..) (thank to Ori Drori for his answer) that has a similar API parameters. Allows you to render in a different part of the DOM, recommended for popups and tooltips.
    (However in my case, no matter how much I tried - I could not make it work)

    *As a side node - the HTMLElement could be any element reference, and not only one created with useRef. You can also use document.getElementById (or other element selector method) or create a new element with document.createElement or with React.createElement.


  2. Use a portal to render a React element inside a DOM node:

    createPortal lets you render some children into a different part of
    the DOM.

    Example:

    import { createPortal } from 'react-dom';
    
    function useRenderExample(ref: React.RefObject<HTMLElement>) {
      const element = ref.current;
      
      return element
        ? createPortal(<h1>HELLO</h1>, element)
        : null
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search