5

Can I sanitize string without using dangerouslySetInnerHTML in React JSX. Requirement is to check the length of sanitized html string and then only include the component. Something like

    var SomeComponent = React.createClass({
       render:function(){
         return (
            {this.props.htmlString.length > 0 ? <Child htmlString={this.props.htmlString} : null}
         )
       }
    })

var Child = React.createClass({
    render:function(){
      return (
        <p dangerouslySetInnerHTML={{__html: this.props.htmlString}}></p>
      )
    }
})

Everything works fine but fails when this.props.htmlString='&nbsp' . In this case length > 0 and component gets included. So I want to check the length of innerHTML before the element inclusion itself.

One Possible Solution I came across is something like :

var html = "&nbsp;";
var div = document.createElement('div');
div.innerHTML = html; //check the length of innerHTML now

But I am looking for a cleaner one more of react type.

3
  • I don't think there's a way with react but let's see what people say.. I'd be interested to know why you're doing this strange code too ;) Commented Jan 8, 2016 at 9:43
  • @DominicTobias For some reason I am getting editor html from rest API. Can't resolve that due to some backlogs Commented Jan 8, 2016 at 9:47
  • The solution you provided is correct - AFAIK there's no other browser API for resolving HTML into plaintext than filling a DOM element with it. Commented Jan 8, 2016 at 9:58

1 Answer 1

2

As you already suggested, resolving a HTML string into plain text is easily done by filling a DOM element with it.

function htmlToText(htmlString) {
  const el = document.createElement('div');
  el.innerHTML = htmlString;
  return el.textContent;
}

This turns your markup into plaintext:

htmlToText('&nbsp;') === '\xa0'  // non-breaking space character

Checking that the resolved text isn't empty is then trivial:

htmlToText('&nbsp;').trim().length === 0
htmlToText('&nbsp; FOO ').trim().length === 3

There's no "React way" to do this, because if you're setting HTML directly from string, it's only resolved when actually injected into the DOM. Of course you could use this tool to create a HOC:

const nonEmptyHtml = Component => props => {
  const html = props.dangerouslySetInnerHTML;
  if (html && !htmlToText(html).trim().length) {
    return null;
  }
  return <Component {...props} />;
};

Usage:

const NonEmptyParagraph = nonEmptyHtml('p');
ReactDOM.render(<NonEmptyParagraph dangerouslySetInnerHTML={htmlString} />);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.