簡體   English   中英

如何同時渲染文本和組件

[英]How to render text and components at the same time

我正在嘗試編寫一個可獲取任何文本字符串,匹配的react組件:URL,電子郵件,提及,標簽並返回Btn組件而不是它們。 有一段代碼:

var StringParser = React.createClass({
  getDefaultProps: function() {
    return {
      type: 'div'
    }
  }

  , callbackMention: function(username) {
    console.log('Mention is ' + username)
  } 

  , callbackTag: function(tag) {
    console.log('Tag is ' + tag)
  } 

  , render: function() {
    var self = this
    var str = self.props.text
    var re = [
      "\\b((?:https?|ftp)://[^\\s\"'<>]+)\\b",
      "\\b(www\\.[^\\s\"'<>]+)\\b",
      "\\b(\\w[\\w.+-]*@[\\w.-]+\\.[a-z]{2,6})\\b", 
      "#([a-z0-9]+)",
      "@([a-z0-9]+)"]
    re = new RegExp(re.join('|'), "gi") 
    var parse = str.replace(re, function(parsed, url, www, email, tag, username){
      if(url && self.props.url) return ( <Btn callback={self.callbackTag} text={url}/> )
      if(www && self.props.url) return ( <Btn callback={self.callbackTag} text={www}/> )
      if(email && self.props.email) return ( <Btn callback={self.callbackTag} text={email}/> )
      if(tag && self.props.tag) return ( <Btn callback={self.callbackTag} text={tag}/> )
      if(username && self.props.username) return ( <Btn callback={self.callbackMention} text={username}/> )
      return parsed
    })
    console.log(parse)
    return React.createElement(self.props.type, self.props, parse)
  }
})

但是當我嘗試解析這樣的行時:

 <StringParser className="stringy" text={'hello www.bar.com#123 mail me at foo@d.com twitler me #123 @user123'}/>

我得到:

hello [object Object] mail me at [object Object] twitler me [object Object] [object Object]

我有兩種方法可以解決問題:

  1. 代替Btn組件,返回'span class =“ ...” onClick =“ this.callbackTag”> ...'

  2. 將對象轉換為字符串。 怎么樣?

如何解決這個問題呢?

String.prototype.replace()強制將您從給定的替換函數返回的所有內容強制轉換為String(因此,您將看到'[object Object]' ),但是您想要保留要創建的React組件作為要渲染的對象由React。

您可以編寫自己的replace函數,該函數返回Array而不是String:

function replaceToArray(text, re, replacer, thisArg) {
  var lastIndex = 0
  var match
  var result = []

  while ((match = re.exec(text)) !== null) {
    // Text preceding the match
    if (lastIndex !== match.index) {
      result.push(text.slice(lastIndex, match.index))
    }
    result.push(replacer.apply(thisArg, match))
    lastIndex = re.lastIndex
  }
  // Text following the last match
  if (lastIndex !== text.length - 1) {
    result.push(text.slice(lastIndex))
  }

  return result
}

然后這應該工作:

var parse = replaceToArray(str, re, function(parsed, url, www, email, tag, username) {
  if (url && this.props.url) return <Btn callback={this.callbackTag} text={url}/>
  if (www && this.props.url) return <Btn callback={this.callbackTag} text={www}/>
  if (email && this.props.email) return <Btn callback={this.callbackTag} text={email}/>
  if (tag && this.props.tag) return <Btn callback={this.callbackTag} text={tag}/>
  if (username && this.props.username) return <Btn callback={this.callbackMention} text={username}/>
  return parsed
}, this)

注意:由於您要返回其中包含組件的Array,如果它們沒有可用於在后續渲染中識別它們的唯一key道具,React將抱怨它們,因此您需要在組件中提供一個如果您想使該警告靜音,則重新生成。

要將它們轉換為字符串,可以使用renderToString或renderToStaticMarkup,但是您可能無法回調。 這就是react-intl處理字符串中的html的方式

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM