简体   繁体   English

使用 JSX 动态添加 HTML 标签

[英]Add HTML tags dynamically using JSX

In the example below, I'd like to find all strings within delimiters:;在下面的示例中,我想查找分隔符内的所有字符串:; and replace them with HTML Mark tags around each match.并将它们替换为 HTML 在每个匹配项周围标记标签。 If it works correctly, those strings should be highlighted in yellow because of the Mark tag.如果它正常工作,由于 Mark 标签,这些字符串应该以黄色突出显示。 Instead, my tags aren't being expanded.相反,我的标签没有被扩展。 Is there a way to do this in JSX?有没有办法在 JSX 中做到这一点?

 function App() { let inputStr = 'This is a:test; of:highlighting;' return ( <div> {HighlightText(inputStr)} </div> ); } function HighlightText(str) { let MyTag = 'Mark'; var matches = str.split(/[:;]/); let outputStr = ''; matches.forEach(m => { const test = ':' + m + ';'; if (str.includes(test)) { outputStr += <MyTag> + m + </MyTag>; } else { outputStr += m; } }); return outputStr; } ReactDOM.render( <App />, document.getElementById("react") );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="react"></div>

As being said in the comments to another answer, I would avoid dangerouslySetInnerHTML for security considerations.正如在另一个答案的评论中所说,出于安全考虑,我会避免dangerouslySetInnerHTML的 SetInnerHTML。

Instead, you may break your string into array of highlighted and non-highlighted sub-strings and render those either as <mark> or regular <span> elements, respectively:相反,您可以将字符串分解为突出显示和未突出显示的子字符串数组,并将它们分别呈现为<mark>或常规<span>元素:

 const { render } = ReactDOM, rootNode = document.getElementById('root'), testString = `This is a:test; of:highlighting;` const App = () => { const subStrings = testString.split(/(:.*?;)/) return ( <div> { subStrings.map((s,key) => /(:.*;)/.test(s)? <mark {...{key}}>{s.slice(1,-1)}</mark>: <span>{s}</span> ) } </div> ) } render ( <App />, rootNode )
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>

Use the /:([^:;]*);/g with String.prototype.split() to get an array like this:使用/:([^:;]*);/gString.prototype.split()来获得这样的数组:

["This is a ", "test", " of ", "highlighting", ""]

Then you can use Array.prototype.flatMap() to group it like this:然后你可以使用Array.prototype.flatMap()像这样对它进行分组:

[["This is a ", "test"], [" of ", "highlighting"], [""]]

Then finally you can use Array.prototype.map() to return a <React.Fragment /> for each inner array above:然后最后你可以使用Array.prototype.map()为上面的每个内部数组返回一个<React.Fragment />

 ReactDOM.render(<App />, document.getElementById('react')); function App() { const inputStr = 'This is a:test; of:highlighting;'; return ( <div>{highlightText(inputStr)}</div> ); } function highlightText(str) { const MyTag = 'Mark'; const matches = str.split(/:([^:;]*);/g); const groups = matches.flatMap( (value, index, array) => ( index % 2 === 0? [array.slice(index, index + 2)]: [] ) ); return groups.map( ([prefix, text], index) => ( <React.Fragment key={index}> {prefix} {text && <MyTag>{text}</MyTag>} </React.Fragment> ) ); } // example function demonstrating that `MyTag` resolves to `<Mark />` function Mark({ children }) { return ( <mark>{children}</mark> ); }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="react"></div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM