关于reactjs:用JSX中的标签替换字符串的一部分

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}
                 
    );
}

但是假设this.props.textLorem : ipsum,则结果为

1
    Lorem [object Object] ipsum.

有没有一种方法可以解决此问题,或者有另一种方法可以用JSX标签替换字符串的一部分?


当您将JSX元素作为第二个参数传递给replace()时,该元素将转换为字符串,因为replace()希望将字符串作为第二个参数。您需要做的是将字符串转换为字符串和JSX元素的数组。因此,您的result变量应包含类似['Lorem ', , ' ipsum']

的内容。

类似这样的内容:

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>')

,然后在元素内使用dangerouslySetInnerHTML进行渲染。

完整示例:

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