РЕДАКТИРОВАТЬ: лучшее объяснение
Контекст:
Я получаю некоторый простой HTML код с третьего сервера, который я хочу
- вставить в мое приложение React
- изменить его
Ванильный JS подход
- Я могу изменить строку с помощью регулярного выражения и добавить любой тег HTML с помощью
id
- Затем я могу изменить эти элементы с помощью
getElementById
, как обычно
Подход React
- Я не должен использовать DOM
- Затем я должен вставить в строку некоторые компоненты, которые имеют ссылку React внутри
- Противоположное (вставить некоторые компоненты React как обычные HTML) было бы через
ReactDOMServer.renderToString
- Итак, когда я добавляю компоненты с помощью
ReactDOM.render()
, проблема заключается в том, что метод render
принимает его время, так что если в следующей строке я пытаюсь использовать ссылку, которая существует во вставленном компоненте, еще нет
Вопрос
- Как это сделать? Обычно я помещаю код в
useEffect
с []
зависимостями, но здесь я rendering
компонент, когда приложение уже смонтировано - Быстрый обходной путь - просто выполнить asyn c подождите 500 мс, и тогда я смогу получить доступ к
ref
, но наверняка должно быть что-то лучше
Этот код не работает, потому что когда ref
отображается по-прежнему недоступен, поэтому ref.current
не определено
Как мне его ждать?
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><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>
);
}