Avoid using dangerouslySetInnerHTML when wrapping HTML in React.js

江枫思渺然 提交于 2020-01-06 19:53:17

问题


I have this functionality for highlighting certain characters in the HTML of my component:

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() {
    return (
        <span dangerouslySetInnerHTML={ {__html: this.highlightQuery()} }></span>
    );
}

So as you can see, if there's no match in this component's value then just return the input contents, else, wrap the matched text in a <span />.

What I'm after, is to avoid using dangerouslySetInnerHTML. Is this possible?


回答1:


I'm not sure this will perfectly answer your question but I would do this to avoid dangerouslySetInnerHTML.

render() {

      highlightQuery() {

        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;
    }

    var mycontent = highlightQuery();

    return (
        <span> {mycontent} </span>
    );

}

hope it helps

Edit: I think I understand what you've meant now but in my opinion it doens't change the strategy, you work inside the render, choose your content and render it. (or maybe I still don't get it.. =p)




回答2:


Is there any reason highlightQuery cannot return a react element?

highlightQuery(input,query, index) {
    // will output the text response from the Model, but also highlight relevant words if they match the search query
    // that the user input
    var before = input.substring(0, index);
    var after  = input.substring(index + query.length);
    return <span>{before}<span class='highlighted'>{query}</span>{after}</span>;
},

render() {
    var input = this.props.model.get('value');
    var query = this.props.matched.query;
    var index = this.props.model.get('searchIndexes')[this.props.matched.index];

    if(!this.state.hasMatch){
        return <span>{input}</span>;
    } else {
        return highlightQuery(input, query, index);
    }

}


来源:https://stackoverflow.com/questions/31805713/avoid-using-dangerouslysetinnerhtml-when-wrapping-html-in-react-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!