反应:如何等到在useEffect()中插入(呈现)ref时可用

This code fails, because when the ref is rendered it is still not available, so ref.current is undefined

我要如何等待?

codesandbox

编辑:我提供了有效但通过直接DOM的代码,我认为应该避免

import React, { useRef, useEffect } from "react";
import ReactDOM from "react-dom";

export default function App() {
  const myref = useRef();

  useEffect(() => {
    const Com = () => <div ref={myref}>hello</div>;
    ReactDOM.render(<Com />, document.getElementById("container"));
    console.log(myref.current); // undefined
    document.getElementById('container').textContent = "direct DOM works"

   // the next line fails since the ref is not yet available
   // myref.current.textContent = "but this REF is not available"; // fails
  }, []);

  const plainhtml = '<div id="container"></div>';

  return (
    <div>
      <h1>Hello CodeSandbox</h1>
      <div dangerouslySetInnerHTML={{ __html: plainhtml }} />
    </div>
  );
}

编辑:

Just to give some context, what I need is to inject components in some html code that I receive from a 3rd server

In plain js I'd access it with document.getElementById(), but here I'm trying to insert some components with react useRefs inside

评论
  • 24K天然
    24K天然 回复

    useEffect with empty dependency array executes after the first render, therefore you will get the DOM ref in the callback:

    const htmlString = '<div id="container">Hello</div>';
    
    export default function App() {
      const myRef = useRef();
    
      useEffect(() => {
        if (myRef.current) {
          myRef.current.textContent = 'whats up';
        }
        console.log(myRef.current);
      }, []);
    
      return (
        <div>
          <div ref={myRef} dangerouslySetInnerHTML={{ __html: htmlString }} />
          <div dangerouslySetInnerHTML={{ __html: htmlString }} />
        </div>
      );
    }
    
    /* App renders:
    whats up
    Hello
    */
    

    Edit nervous-glade-8rtxb