React.js - conditionally use dangerouslySetInnerHTML

11,862

Solution 1

You can define an element (and its properties) before calling the render function, like so:

var return = {};
if(myCondition) {
    return = <span key={this.props.model.cid} className={classes}>
                {!this.state.hasMatch && this.highlightQuery()}
             </span>
} else {
    return = <span key={this.props.model.cid} className={classes} dangerouslySetInnerHTML={ {__html: this.highlightQuery()} }></span>
}

Then you can just render the return var.

Solution 2

and make sure you do not include a space between the span tags else you would run into the following error:

invariant.js:39 Uncaught Invariant Violation: Can only set one of children or props.dangerouslySetInnerHTML.

return = <span key={this.props.model.cid} className={classes} dangerouslySetInnerHTML={ {__html: this.highlightQuery()} }>NO SPACE OR TEXT HERE</span>

Solution 3

You can use spread syntax if you are using ES2016.

const options = {};
if (useHTML) {
  options.dangerouslySetInnerHTML = {__html: yourHTML};
} else {
  options.children = [<ChildNode/>];
}
return <span {...options} className="myClassName"></span>
Share:
11,862

Related videos on Youtube

benhowdle89
Author by

benhowdle89

Consultant software engineer and advisor to companies building software products.

Updated on September 16, 2022

Comments

  • benhowdle89
    benhowdle89 over 1 year

    I have some code to Regex some text and wrap it in a <span /> like so:

    highlightQuery() {
        // will output the text response from the Model, but also highlight relevant words if they match the search query
        // that the user input
        let input = this.props.model.get('value');
    
        if(!this.state.hasMatch){
            return input;
        }
    
        let query = this.props.matched.query,
            index = this.props.model.get('searchIndexes')[this.props.matched.index];
    
        const replaceBetween = (str, start, end, what) => {
            return str.substring(0, start) + what + str.substring(start + end);
        };
    
        let ret = replaceBetween(input, index, query.length, `<span class='highlighted'>${query}</span>`);
    
        return ret;
    },
    
    render() {
    
        const classes = classNames(
            this.props.model.get('type'),
            'character'
        );
    
        return (
            <span key={this.props.model.cid} className={classes} dangerouslySetInnerHTML={ {__html: this.highlightQuery()} }>
                {!this.state.hasMatch && this.highlightQuery()}
            </span>
        );
    }
    

    However, this yields: Uncaught Error: Invariant Violation: Can only set one of children or props.dangerouslySetInnerHTML.

    How am I best to conditionally use dangerouslySetInnerHTML?

  • Aviran
    Aviran over 7 years
    you probably want a better name than 'return' for a variable.
  • saawsann
    saawsann about 7 years
    In my case, I had a linebreak between the opening and closing tag. It generated the following warning Only set one of children or props.dangerouslySetInnerHTML - react/no-danger-with-children.
  • abettermap
    abettermap over 4 years
    In case you want to investigate/ignore the potential eslint complaint which might show up in regards to prop spreading, here are the docs for it.