javascript - How to render text and components at the same time -


i'm trying write react component gets text string, match: urls, emails, mentions, tags , returns btn components instead of them. there snippet of code:

var stringparser = react.createclass({   getdefaultprops: function() {     return {       type: 'div'     }   }    , callbackmention: function(username) {     console.log('mention ' + username)   }     , callbacktag: function(tag) {     console.log('tag ' + tag)   }     , render: function() {     var self =     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)   } }) 

but when try parse such line:

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

i get:

hello [object object] mail me @ [object object] twitler me [object object] [object object] 

i have 2 ways solve problem:

  1. instead of btn component return 'span class="..." onclick="this.callbacktag">...'

  2. convert objects string. how?

how solve problem?

string.prototype.replace() coerces whatever return given replacer function string (hence '[object object]' you're seeing), want retain react components you're creating objects rendered react.

you write own replace function returns array rather string:

function replacetoarray(text, re, replacer, thisarg) {   var lastindex = 0   var match   var result = []    while ((match = re.exec(text)) !== null) {     // text preceding match     if (lastindex !== match.index) {       result.push(text.slice(lastindex, match.index))     }     result.push(replacer.apply(thisarg, match))     lastindex = re.lastindex   }   // text following last match   if (lastindex !== text.length - 1) {     result.push(text.slice(lastindex))   }    return result } 

then should work:

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) 

note: since you're returning array components in it, react complain if don't have uniquekey prop can use identify them on subsequent renders, you'll need provide 1 in components you're generating if want silence warning.


Comments

Popular posts from this blog

Email notification in google apps script -

c++ - Difference between pre and post decrement in recursive function argument -

javascript - IE11 incompatibility with jQuery's 'readonly'? -