在下面的示例中,我希望找到分隔符:;中的所有字符串,并将它们替换为每个匹配项周围的HTML标记标记。如果它工作正常,由于Mark标记,这些字符串应该以黄色突出显示。相反,我的标签并没有被扩展。在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>
发布于 2020-05-14 05:42:23
正如在对另一个答案的评论中所说的,出于安全考虑,我会避免使用dangerouslySetInnerHTML。
相反,您可以将字符串分解为高亮显示和非高亮显示的子字符串数组,并将它们分别呈现为<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>
发布于 2020-05-14 05:36:31
使用带有String.prototype.split()的/:([^:;]*);/g来获得如下数组:
["This is a ", "test", " of ", "highlighting", ""]然后,您可以使用Array.prototype.flatMap()对其进行分组,如下所示:
[["This is a ", "test"], [" of ", "highlighting"], [""]]最后,您可以使用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>
https://stackoverflow.com/questions/61784643
复制相似问题