2017-08-15 48 views
1

反应组分我有来自服务器,例如一个HTML字符串:渲染定制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); 

但这需要相当复杂的逻辑,因为可能有一个<p>标签,有内有多个[[dropdown]]小号也可以嵌套标签。

所以我现在卡住了。也许我从一个非常奇怪的角度看待这个问题,这可以在React中以不同的方式完成。我知道React社区不鼓励从字符串中呈现HTML,但我无法绕过这一点,我总是必须从服务器接收文本。

我发现唯一相关的stackoverflow问题是this one,但是,它假设来自后端的内容始终具有相同的结构,因此无法在我的情况下使用它,因为内容可以是任何内容。

编辑: 经过一些挖掘后,我发现这个question and answer这似乎有点解决我的问题。但是,使用react-dom/server包与renderToString方法将我的组件翻译为字符串并将其连接起来,仍然感觉有点奇怪。但我会试一试,并会发布更多的信息,如果它的工作,并符合我的需求。

回答

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(''); 

那么对于componentDidMountcomponentDidUpdate,请拨打以下方法:

_renderDropdowns() { 
    this.dropdownComponents.forEach((dropdownComponent) => { 
     const container = document.getElementById(dropdownComponent.selector); 
     ReactDOM.render(dropdownComponent.component, container); 
    }); 
    } 

这将确保该span标签与特定的下拉ID中有什么会由组件取代。在componentDidMountcomponentDidUpdate中有上述方法可以确保当你传递任何新的道具时,道具将被更新。在我的例子中,我没有传递任何道具,但在现实世界的例子中,你通常会传递道具。

因此,毕竟,我不必使用react-dom/serverrenderToString