Replace part of string with tag in JSX
我正在尝试用JSX标签替换字符串的一部分,例如:
1 2 3 4 5 6 7 8 | render: function() { result = this.props.text.replace(":",); return ( {result} ); } |
但是假设
1 | Lorem [object Object] ipsum. |
有没有一种方法可以解决此问题,或者有另一种方法可以用JSX标签替换字符串的一部分?
当您将JSX元素作为第二个参数传递给
的内容。
类似这样的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | function flatMap(array, fn) { var result = []; for (var i = 0; i < array.length; i++) { var mapping = fn(array[i]); result = result.concat(mapping); } return result; } var Comp = React.createClass({ render: function () { var result = 'Lorem : ipsum'; result = flatMap(result.split(':'), function (part) { return [part, spacer]; }); // Remove the last spacer result.pop(); return ( {result} ); } }); |
可接受的答案已经两岁了。针对此问题,创建了问题3368,并根据一位从事React的Facebook员工提供的解决方案,创建了react-string-replace。
使用react-string-replace,这是解决问题的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | const reactStringReplace = require('react-string-replace'); const HighlightNumbers = React.createClass({ render() { const content = 'Hey my number is 555:555:5555.'; return ( <span> {reactStringReplace(content, ':', (match, i) => ( ))} </span> ); }, }); |
以下内容也应该起作用(假设为ES6),唯一的细微差别是,该文本实际上是包裹在DIV元素中的,而不是紧随其后的,假设您要使用CSS作为实际间距,这不应该是问题。
1 2 3 | const result = this.props.text.split(':').map(t => { return {t}; }); |
为jsx编写实用程序功能。
1 2 3 4 5 6 7 8 9 | const wrapTags = (text: string, regex: RegExp, className?: string) => { const textArray = text.split(regex); return textArray.map(str => { if (regex.test(str)) { return <span className={className}>{str}</span>; } return str; }); }; |
你们正在使用复杂的方法,只需保持简单即可:
1 2 3 4 5 6 7 8 9 10 | function replaceJSX(str, find, replace) { let parts = str.split(find); for(let i = 0, result = []; i < parts.length; i++) { result.push(parts[i]); result.push(replace); } return ( <>{result}</> ); } |
用法
1 | replaceJSX(variable,":", <br />); |
经过研究,我发现现有的库不符合我的要求。所以,我当然写了我自己的书:
https://github.com/EfogDev/react-process-string
它非常易于使用。您的案例示例:
1 2 3 4 | let result = processString({ regex: /:/gim, fn: () => })(this.props.test); |
我有一个比较常见的任务-用自定义标签包裹所有(英文)单词。
我的解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | class WrapWords extends React.Component { render() { const text = this.props.text; const isEnglishWord = /\\b([-'a-z]+)\\b/ig; const CustomWordTag = 'word'; const byWords = text.split(isEnglishWord); return ( { byWords.map(word => { if (word.match(isEnglishWord)) { return <CustomWordTag>{word}</CustomWordTag>; } return word; }) } ); } } // Render it ReactDOM.render( <WrapWords text="Argentina, were playing: England in the quarter-finals (the 1986 World Cup in Mexico). In the 52nd minute the Argentinian captain, Diego Maradona, scored a goal." />, document.getElementById("react") ); |
1 2 | <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"> |
除此解决方案外,WEB全球范围内没有任何工作对我有效-https://www.npmjs.com/package/regexify-string
使用React,字符串并且没有任何其他依赖项
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | regexifyString({ pattern: /\\[.*?\\]/gim, decorator: (match, index) => { return ( <Link to={SOME_ROUTE} onClick={onClick} > {match} </Link> ); }, input: 'Some text with [link]', }); |
我认为这是最轻巧的完美解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | render() { const searchValue ="an"; const searchWordRegex = new RegExp(searchValue,"gi"); const text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text"; return ( {text.split(searchWordRegex).length > 1 ? text.split(searchWordRegex).map((chunk, index) => { if (chunk !=="") { return index === 0 && ! new RegExp("^" + searchValue,"gi").test(text) ? ( chunk ) : ( <span key={index}> <span className="highlight" style={{ fontWeight:"bold" }} > {searchValue.charAt(0).toUpperCase() + searchValue.slice(1)} </span> {chunk} </span> ); } else { return null; } }) : text} ); } |
and here is a working example
我来到了一个不包含第三方库或正则表达式的简单解决方案,也许它仍然可以帮助某人。
主要只是使用.replace()将字符串替换为以字符串形式编写的常规html,例如:
1 | text.replace('string-to-replace', '<span class="something"></span>') |
,然后在元素内使用
完整示例:
1 2 3 4 5 6 7 8 9 10 11 | const textToRepace = 'Insert :' // we will replace : with div spacer const content = textToRepace.replace(':', '') : '' // then in rendering just use dangerouslySetInnerHTML render() { return( <div dangerouslySetInnerHTML={{ __html: content }} /> ) } |
带有钩子的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import React, { useEffect, useState, useRef } from 'react' export function Highlight({ value, highlightText }) { const [result, resultSet] = useState(wrap()) const isFirstRun = useRef(true) function wrap() { let reg = new RegExp('(' + highlightText + ')', 'gi') let parts = value.split(reg) for (let i = 1; i < parts.length; i += 2) { parts[i] = ( <span className='highlight' key={i}> {parts[i]} </span> ) } return {parts} } useEffect(() => { //skip first run if (isFirstRun.current) { isFirstRun.current = false return } resultSet(wrap()) }, [value, highlightText]) return result } |
如果您还希望能够在替换中进行替换(例如,突出显示URL中的搜索词),请查看我创建的该节点模块-https://github.com/marcellosachs/react-string -recursively