Skip to content Skip to sidebar Skip to footer

Call React Component Function From Onclick In Dangerouslysetinnerhtml

React newbie here. I have a contenteditable div which has dangerouslySetInnerHTML as the child, since I need to format whatever the user enters,at runtime. On a particular span cli

Solution 1:

If you want your spans to respond to click events, you should assign event handler(doSomething) only after your component is rerendered, because when you assing new value to innerHtml, all event handlers within this component are cleaned. Another solution is using event delegation like this:

onClick: function(e) {
    var $el = $(e.target);
    if ($el.is('span.tagged')) {
        this.doSomething($el);
    }
},

render:function(){
    return (
        <divclassName="inputDiv form-control"contentEditable="true"onClick={this.onClick}type="text"id="text_Box"dangerouslySetInnerHTML={{__html:this.state.userText}} 
            onInput={this.updateText} />
    );
}

Another possible solution is to work with DOM tree directly using createElement, createTextNode and appendChild methods.

Solution 2:

Try this:

updateText: function() {
    var txt = $('#text_Box').text();

    if (txt.indexOf('@Name') > -1) {
        txt = txt.replace('@Name', '<span class="tagged" contenteditable="false" onclick="' + this.doSomething() + '">:Name</span>');
    }
    this.setState({userText: txt});
}, 

render:function(){
    return (
        <divclassName="inputDiv form-control"contentEditable="true"type="text"id="text_Box"dangerouslySetInnerHTML={{__html:this.state.userText}} 
            onInput={this.updateText} />
    );
}

Solution 3:

I had a similar requirement recently. The react app was being given a block of html with href attributes that needed to be converted into onClick events so that we could resolve and route the links within the react app.

My solution was to use regex and then register my own event listeners

//given a block of html as a string
myHtml = '<div href="/goSomewhere"></div>'//match all href attributesletreg: RegExp = /href=".*?"/g//replace the href attribute with a custom "resolve" attribute
myHtml.replace(reg, (href: string) => {
  //then match any characters between the quotation marks in the href attribute to extract the uri itselflet uri = href.match(/(?<=href=").*?(?=")/g)
  return`resolve="${uri}"`
})


//Render the htmlrender() { 
   return<divdangerouslySetInnerHTML = {{__html:myHtml}} />
}

//helper function to return an array containing all nodes with a "resolve" attributegetElementByAttribute(attr: string) {
  let nodeList = document.getElementsByTagName('*')
  let nodeArray = []
  for (let i = 0; i < nodeList.length; i++) {
    if (nodeList[i].getAttribute(attr)) nodeArray.push(nodeList[i])
  }
  return nodeArray
}

//once rendered find the tag that require resolving componentDidUpdate() {
  let nodes = this.getElementByAttribute('resolve')
  for (let i = 0; i < nodes.length; i++) {
    //create pointer outside of the onclick event allowing closurelet href = nodes[i].getAttribute('resolve')

    nodes[i].addEventListener('click', (e) => {
      if (href) this.linkResolver(href);
    })

    //remove the custom attribute to cleanup
    nodes[i].removeAttribute('resolve')
  }
}

//linkResolver is a function within react//you now have an onclick event triggered from dangerouslySetInnerHTMLlinkResolver(href: string) {
  console.log(href)
}

Post a Comment for "Call React Component Function From Onclick In Dangerouslysetinnerhtml"