#reactjs
#reactjs
Вопрос:
Мне нужно сгенерировать HTML-текст, а затем отобразить его в текстовой области, чтобы легко скопировать его.
Вот упрощенная версия моего кода (CodeSandbox):
function Text({ foo }) {
return (
<>
<h2>Title</h2>
{foo amp;amp; <p>Foot</p>}
<p>Baar</p>
</>
);
}
export default function App() {
const [toggle, setToggle] = useState(true);
return (
<div className="App">
<button
onclick={() => {
setToggle(!toggle);
}}
>
Toogle!
</button>
<hr />
<h2>Preview</h2>
<Text foo={toggle} />
<hr />
<h2>HTML code :</h2>
<textarea value={<Text foo={toggle} />} />
</div>
);
}
Компонент возвращает [object объект]. Как я могу вернуть html?
Ответ №1:
Вам нужно будет использовать ReactDOMServer.renderToString(element)
для преобразования HTML-кода компонента в строку. Вы также можете присвоить компоненту переменную, чтобы гарантировать, что значение html, которым вы заполняете текстовую область, и предварительный просмотр, отображаемый в возврате, ссылаются на один и тот же экземпляр компонента.
Документация здесь: ReactDOMServer
import React, { useState } from "react";
import ReactDOMServer from "react-dom/server";
import "./styles.css";
function Text({ foo }) {
return (
<>
<h2>Title</h2>
{foo amp;amp; <p>Foo</p>}
<p>Baar</p>
</>
);
}
export default function App() {
const [toggle, setToggle] = useState(true);
const element = <Text foo={toggle} />;
const html = ReactDOMServer.renderToString(element);
console.log(element);
return (
<div className="App">
<button
onClick={() => {
setToggle(!toggle);
}}
>
Toogle!
</button>
<hr />
<h2>Preview</h2>
{element}
<hr />
<h2>HTML code :</h2>
<textarea value={html} />
</div>
);
}
Ответ №2:
Я не думаю, что вы сможете это сделать, поскольку это не HTML семантически корректно. Я попытался отредактировать ваш CodeSendbox, чтобы поместить внутри текстовой области dangerouslySetInnerHTML, и он отобразил сообщение о том, что нет смысла отображать html-элементы внутри текстовой области. Что вы можете сделать, это использовать некоторый div вместо textarea и предоставить ему несколько классов css, чтобы он выглядел как textarea, и поместить в него contenteditable в качестве атрибута, вот так:
export default function App() {
const [toggle, setToggle] = useState(true);
return (
<div className="App">
<button
onClick={() => {
setToggle(!toggle);
}}
>
Toogle!
</button>
<hr />
<h2>Preview</h2>
<Text foo={toggle} />
<hr />
<h2>HTML code :</h2>
<div contentEditable className="divAsTextarea">
<Text foo={toggle} />
</div>
</div>
);
}