2017-08-15 49 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