最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Replace subsring by an HTML tag in react - Stack Overflow

programmeradmin1浏览0评论

How can i surround certain letters in a string by an html tag?

For example, given this string: Sgt. Pepper's Lonely Hearts Club Band and this substring: Pepp. I want to surround the substring inside the string with an html tag. Like this: Sgt. <mark class="Search-suggestions-match">Pepp</mark>er's Lonely Hearts Club Band.

I achieved this, but React is escaping the span tags. But also, i don't know if i should take another approach, maybe a more JSX one.

This is the ponent where im trying to implement it:

class SearchSuggestions extends Component {

    constructor(props) {
        super(props)

        if (!this.props.suggestions || !this.props.term) {
            return
        }

        this.state = {
            suggestions : this.props.suggestions.map(item => this.markText(item))
        }
    }

    markText(string) {
        return string.replace(new RegExp(this.props.term, "ig"), match => {
            return `<mark class="Search-suggestions-match">${match}</mark>`
        })
    }

    render() {
        if (!this.props.suggestions || !this.props.term) {
            return null
        }
        return (
            <ul className="Search-suggestions-ponent">
                {this.state.suggestions.map((value, i) => <li key={i}>{value}</li>)}
            </ul>
        )
    }
}

How can i surround certain letters in a string by an html tag?

For example, given this string: Sgt. Pepper's Lonely Hearts Club Band and this substring: Pepp. I want to surround the substring inside the string with an html tag. Like this: Sgt. <mark class="Search-suggestions-match">Pepp</mark>er's Lonely Hearts Club Band.

I achieved this, but React is escaping the span tags. But also, i don't know if i should take another approach, maybe a more JSX one.

This is the ponent where im trying to implement it:

class SearchSuggestions extends Component {

    constructor(props) {
        super(props)

        if (!this.props.suggestions || !this.props.term) {
            return
        }

        this.state = {
            suggestions : this.props.suggestions.map(item => this.markText(item))
        }
    }

    markText(string) {
        return string.replace(new RegExp(this.props.term, "ig"), match => {
            return `<mark class="Search-suggestions-match">${match}</mark>`
        })
    }

    render() {
        if (!this.props.suggestions || !this.props.term) {
            return null
        }
        return (
            <ul className="Search-suggestions-ponent">
                {this.state.suggestions.map((value, i) => <li key={i}>{value}</li>)}
            </ul>
        )
    }
}
Share Improve this question asked Jul 19, 2017 at 18:07 Toni OriolToni Oriol 732 silver badges8 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

Use a regular expression to split the string, capturing the desired match, and then format it with JSX:

markText(string) {
    let strArr = string.split(new RegExp(`(${this.props.term})`, "ig"));
    return strArr.map((ea, i) => {
      if(ea.toLowerCase() === this.props.term.toLowerCase()){
        return <mark key={`match${i}`} className="Search-suggestions-match">{ea}</mark>
      } else {
        return ea;
      }
    });
}

HTML inside of a string will NOT get added to the DOM, so you need to use JSX to return an actual React element instead.

Edit: added toLowerCase() so that matches will ignore letter case like they do in the regular expression.

Typically you should not pass JSX as a string and expect React to render the element.

However there is an escape hatch that can be used to achieve what you want, check out dangerouslySetInnerHTML

From the docs:

dangerouslySetInnerHTML is React's replacement for using innerHTML in the browser DOM. In general, setting HTML from code is risky because it's easy to inadvertently expose your users to a cross-site scripting (XSS) attack. So, you can set HTML directly from React, but you have to type out dangerouslySetInnerHTML and pass an object with a __html key, to remind yourself that it's dangerous

So you could still do something like this:

render() {

  ...

  return (
    <ul className="Search-suggestions-ponent">
      {
        this.state.suggestions.map((value, i) => (
          <li key={i} dangerouslySetInnerHTML={{ __html: value }} />
        )
      }
    </ul>
  )
}
发布评论

评论列表(0)

  1. 暂无评论