When using React, you will want to move the selection logic outside of the render function
stateShape:
{ content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent tristique elit in volutpat iaculis. Proin a tincidunt turpis, et condimentum libero. Duis convallis nulla eu mattis porta. Nulla facilisi. Proin nec viverra orci. Nunc aliquam enim orci, ut dictum ipsum auctor ut. Quisque consectetur vestibulum tortor, mollis hendrerit velit hendrerit vel. In hac habitasse platea dictumst. Morbi volutpat lectus purus, eu sagittis odio viverra in. Phasellus vel volutpat felis. Proin a metus sit amet ipsum congue faucibus nec faucibus nisl. Aenean eu nisl ac velit dapibus vulputate non efficitur urna. Phasellus laoreet suscipit dictum. Curabitur sit amet justo at nisi dictum dapibus.", highlights: [{ id: 1, wordIndexStart: 0, wordIndexEnd: 5, note: "Some note" }, { id: 2, wordIndexStart: 6, wordIndexEnd: 10, note: "Some other note" }] }
connected component of mapStateToProps:
function mapStateToProps(state, ownProps) { const { content, highlights } = state; // Move this logic to ReSelect? https://github.com/reactjs/reselect const words = content.split(" "); const wordsWithHighlights = words.map((word, index) => { const highlightStart = highlights.find((highlightItem) => { return highlightItem.wordIndexStart == index; }); if (highlightStart) { return `<span title=${highlightStart.note}>${word}`; } const highlightEnd = highlights.find((highlightItem) => { return highlightItem.wordIndexEnd == index; }); if (highlightEnd) { return `${word}</span>`; } return word; }); return { content: wordsWithHighlights.join(" ") }; }
and then the render function:
render() { const { content } = this.props; return ( <p dangerouslySetInnerHTML={{ __html: content }} /> ) }
As @jordan pointed out, you cannot add HTML as a string in React, and according to this answer, you can use the dangerouslySetInnerHTML attribute as above
source share