EDIT: better explanation
The context:
I receive some plain HTML code from a 3rd server, which I want to
- insert in my React app
- modify it
The vanilla JS approach
- I can modify the string with regex and add any HTML tag with an
id - Then I can modify these elements through
getElementById, as usual
The React approach
- I shouldn't use the DOM
- Then I should insert within the string some components that have a React ref inside
- The opposite (to insert some React components as plain HTML) would be through
ReactDOMServer.renderToString - So, when I inject the components with
ReactDOM.render(), the problem is that therendermethod takes its time, so that if in the next line I try to use the ref that exists in the inserted component, is not yet there
The question
- How to do it? Usually I would put the code within a
useEffectwith a[]dependencies, but here I amrenderingthe component when the app is already mounted - A quick workaround is to just do an async wait of 500 ms, and then I can access the
ref, but for sure there has to be something better
This code fails, because when the ref is rendered it is still not available, so ref.current is undefined
How can I wait for it?
EDIT: I provide the code that works but through direct DOM, which I assume should be avoided
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><div id="container"></div><div>some more content</div><div id="another">even more content</div></div>'; // this is some large HTML fetched from an external server
return (
<div>
<h1>Hello CodeSandbox</h1>
<div dangerouslySetInnerHTML={{ __html: plainhtml }} />
</div>
);
}
