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:
instead of btn component return 'span class="..." onclick="this.callbacktag">...'
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
Post a Comment