我有一个来自服务器的HTML字符串,例如:
const myString = '<p>Here goes the text [[dropdown]] and it continues</p>`;
我将这个字符串分成3个部分,结果如下:
const splitString = [
'<p>Here goes the text ',
'[[dropdown]]',
' and it continues</p>'
];
然后我处理这3个部分,以便用反应成分替换下拉列表:
const processedArr = splitString.map((item) => {
if (/* condition that checks if it's `[[dropdown]]` */) {
return <Dropdown />;
}
return item;
}
毕竟,我得到了处理后的数组,如下所示:
['<p>Here goes the text ', <Dropdown />, ' and it continues</p>']
当我渲染它时,它将HTML作为文本(显然)呈现为文本之间的Dropdown
组件(正确呈现)。这里的问题是我无法使用{ __html: ... }
,因为必须使用<div dangerouslySetInnerHTML={{ __html: ... }} />
。我无法在字符串周围添加<div>
,因为这样会删除<p>
标记。
我考虑过将部分拆分成标签,然后在某种循环中执行类似的操作:
React.createElement(tagName, null, firstTextPart, reactComponent, secondTextPart);
但这需要相当复杂的逻辑,因为在一个[[dropdown]]
标记内可能有多个<p>
,并且也可能存在嵌套标记。
所以我现在被困住了。也许我从一个非常奇怪的角度看问题,这可以在React中以不同的方式实现。我知道React社区不鼓励从字符串中呈现HTML,但我不能解决这个问题,我总是要从服务器接收文本。
我发现唯一相关的stackoverflow问题是this one,但是假设来自后端的内容总是具有相同的结构,因此在我的情况下不能使用内容可以是任何内容。
编辑:
经过一番挖掘,我发现这question and answer似乎有点解决了我的问题。但是使用react-dom/server
包及其renderToString
方法将我的组件转换为字符串然后连接它仍然感觉有点奇怪。但我会尝试一下,如果有效并符合我的需要,会发布更多信息。
答案 0 :(得分:0)
所以在玩完代码之后,我终于找到了一个“解决方案”。它并不完美,但我还没有找到任何其他方法来完成我的任务。
我没有按照我的方式处理splitString
。 .map
看起来会有所不同:
// Reset before `.map` and also set it up in your component's constructor.
this.dropdownComponents = [];
const processedArr = splitString.map((item) => {
if (/* condition that checks if it's `[[dropdown]]` */) {
const DROPDOWN_SELECTOR = `dropdown-${/* unique id here */}`;
this.dropdownComponents.push({
component: <Dropdown />,
selector: DROPDOWN_SELECTOR
});
return `<span id="${DROPDOWN_SELECTOR}"></span>`;
}
return item;
}).join('');
然后,对于componentDidMount
和componentDidUpdate
,请调用以下方法:
_renderDropdowns() {
this.dropdownComponents.forEach((dropdownComponent) => {
const container = document.getElementById(dropdownComponent.selector);
ReactDOM.render(dropdownComponent.component, container);
});
}
它将确保具有特定下拉列表ID的span
标记内的内容将被组件替换。在componentDidMount
和componentDidUpdate
中使用上述方法可确保在传递任何新道具时,道具将会更新。在我的例子中,我没有传递任何道具,但在现实世界的例子中,你通常会传递道具。
毕竟,我不必使用react-dom/server
renderToString
。
答案 1 :(得分:0)
如何将文本分开并单独渲染组件?
你的反应组件应如下所示(在JSX中):
<div>
<span>first text</span>
{props.children} // the react component you pass to render
<span>second part of the text</span>
</div>
你只需用以下内容调出这个组件:
<MessageWrapper>
<DropdownComponent/> // or whatever
</MessageWrapper>