Javascript 如何同时呈现文本和组件

Javascript 如何同时呈现文本和组件,javascript,reactjs,Javascript,Reactjs,我正在尝试编写一个react组件,它可以获取任何文本字符串,匹配:URL、电子邮件、提及、标记和返回Btn组件,而不是它们。有一段代码: var StringParser = React.createClass({ getDefaultProps: function() { return { type: 'div' } } , callbackMention: function(username) { console.log('Mention i

我正在尝试编写一个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)
  }
})
我有两种解决问题的方法:

  • 而不是Btn组件返回'span class=“…”onClick=“this.callbackTag”>…'

  • 将对象转换为字符串。怎么做


  • 如何解决此问题?

    要将它们转换为可以使用的字符串,或renderToStaticMarkup,但可能会失去回调功能。这就是react intl如何将从给定替换函数返回的任何内容强制转换为字符串(因此就是您看到的
    “[object object]”
    ),但您希望将正在创建的react组件保留为react渲染的对象

    您可以编写自己的replace函数,该函数返回数组而不是字符串:

    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)
    
    var parse=replaceToArray(str、re、function(已解析、url、www、电子邮件、标记、用户名){
    if(url&&this.props.url)返回
    如果(www&&this.props.url)返回
    如果(电子邮件和此.props.email)返回
    if(tag&&this.props.tag)返回
    if(username&&this.props.username)返回
    返回解析
    },本页)
    

    注意:由于您返回的是一个包含组件的数组,如果它们没有一个唯一的
    键,React将发出抱怨,它可以在后续渲染中使用该键来识别它们,因此如果您想消除该警告,您需要在生成的组件中提供一个。

    +1;只是想补充一点,因为有时候很容易忘记,JSX不是HTML,键入
    不会生成字符串。它是一个物体。
    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)