【问题标题】:Insert HTML with React Variable Statements (JSX) [duplicate]使用 React 变量语句(JSX)插入 HTML [重复]
【发布时间】:2014-06-30 05:46:00
【问题描述】:

我正在使用 React 构建一些东西,我需要在 JSX 中插入带有 React 变量的 HTML。有没有办法有一个像这样的变量:

var thisIsMyCopy = '<p>copy copy copy <strong>strong copy</strong></p>';

并像这样将它插入到反应中,并让它工作?

render: function() {
    return (
        <div className="content">{thisIsMyCopy}</div>
    );
}

并让它按预期插入 HTML?我还没有看到或听说过任何关于可以内联执行此操作的反应函数,或解析可以使其工作的事物的方法。

【问题讨论】:

    标签: javascript html frontend reactjs react-jsx


    【解决方案1】:

    你可以使用dangerouslySetInnerHTML,例如

    render: function() {
        return (
            <div className="content" dangerouslySetInnerHTML={{__html: thisIsMyCopy}}></div>
        );
    }
    

    【讨论】:

    • 如果您需要向&lt;head&gt; 添加内容,这将如何工作?
    • componentDidMount 中的普通 DOM 方法应该可以工作,不过我之前没有这样做过。
    • @DanielleMadeley 您是否要在 中插入条件 IE cmets?如果是这样,我已经使用此处描述的技巧取得了成功:nemisj.com/conditional-ie-comments-in-react-js
    • 确保将方法传递给 dangerouslySetInnerHTML 而不是散列。根据文档,仅传递哈希是危险的。参考:facebook.github.io/react/tips/dangerously-set-inner-html.html
    • 有没有不插入div的方法?
    【解决方案2】:

    请注意,如果您不知道要注入的 HTML 字符串中的内容,dangerouslySetInnerHTML 可能会很危险。这是因为可以通过脚本标签注入恶意客户端代码。

    如果您不能 100% 确定要呈现的 HTML 是 XSS(跨站脚本)安全的,那么通过 DOMPurify 等实用程序清理 HTML 字符串可能是个好主意.

    例子:

    import DOMPurify from 'dompurify'
    
    const thisIsMyCopy = '<p>copy copy copy <strong>strong copy</strong></p>';
    
    
    render: function() {
        return (
            <div className="content" dangerouslySetInnerHTML={{__html: DOMPurify.sanitize(thisIsMyCopy)}}></div>
        );
    }
    

    【讨论】:

    • @vsync 不应该:)
    • 是否不仅可以渲染 html 标签,还可以渲染来自库的标签,如材料 ui Alert 标签。我希望代码是这样的import DOMPurify from 'dompurify' const thisIsMyCopy = '&lt;Alert severity="warning"&gt;copy copy copy &lt;strong&gt;strong copy&lt;/strong&gt;&lt;/Alert &gt;'; render: function() { return ( &lt;div className="content" dangerouslySetInnerHTML={{__html: DOMPurify.sanitize(thisIsMyCopy)}}&gt;&lt;/div&gt; ); }
    • @sasharomanov,你有没有为这种情况找到任何解决方案?
    【解决方案3】:

    dangerouslySetInnerHTML 有很多缺点,因为它设置在标签内。

    我建议您使用一些反应包装器,就像我在 npm 上找到的一样用于此目的。 html-react-parser 做同样的工作。

    import Parser from 'html-react-parser';
    var thisIsMyCopy = '<p>copy copy copy <strong>strong copy</strong></p>';
    
    
    render: function() {
        return (
            <div className="content">{Parser(thisIsMyCopy)}</div>
        );
    }
    

    非常简单:)

    【讨论】:

    • "dangerouslySetInnerHTML 有很多缺点,因为它设置在标签内。"你能解释一下吗?试图弄清楚 html-react-parser 和 sanatized innerHtml 之间有什么根本区别
    • 似乎 html-react-parser 没有清理输入 - 请参阅常见问题解答
    【解决方案4】:

    如果还有其他人在这里登陆。使用 ES6,您可以像这样创建 html 变量:

    render(){
        var thisIsMyCopy = (
            <p>copy copy copy <strong>strong copy</strong></p>
        );
        return(
            <div>
                {thisIsMyCopy}
            </div>
        )
    }
    

    【讨论】:

    • 如果你想在你的字符串中包含变量,你需要将每个变量包装在{}中,并将整个字符串包装在一些标记中,比如(&lt;span&gt;{telephoneNumber} &lt;br /&gt; {email}&lt;/span&gt;)
    • 这与问题中提出的不同。在问题中&lt;p&gt;copy copy copy &lt;strong&gt;strong copy&lt;/strong&gt;&lt;/p&gt; 是一个字符串。你有它作为 JSX。
    • 那不是 ES6,而是 JSX
    【解决方案5】:

    你也可以像这样在 ReactDOM 中包含这个 HTML:

    var thisIsMyCopy = (<p>copy copy copy <strong>strong copy</strong></p>);
    
    ReactDOM.render(<div className="content">{thisIsMyCopy}</div>, document.getElementById('app'));
    

    这里有两个链接 linklink2 来自 React 文档,它们可能会有所帮助。

    【讨论】:

      【解决方案6】:

      通过使用'',您可以将其变成一个字符串。使用不带引号的就可以了。

      const App = () => {
      const span = <span> whatever your string </span>
      
      const dynamicString = "Hehe";
      const dynamicStringSpan = <span> {`${dynamicString}`} </span>
      
        return (
          <div>
      
            {span}
      
            {dynamicStringSpan}
      
          </div>
        );
      
      };
      
      ReactDOM.render(<App />, document.getElementById("root"));
      <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
      <div id="root"></div>

      【讨论】:

      • 迄今为止最简单的答案,尤其是如果 HTML 是由您编写并根据用户输入动态生成的。你可以从字面上设置 var myHtml =

        Some text

        ;它有效
      • 我认为它适用于动态生成的字符串(例如,来自用户生成的内容),您的解决方案将不起作用。不过谢谢!
      【解决方案7】:

      为了避免 linter 错误,我这样使用它:

        render() {
          const props = {
            dangerouslySetInnerHTML: { __html: '<br/>' },
          };
          return (
              <div {...props}></div>
          );
        }
      

      【讨论】:

        【解决方案8】:
        import { Fragment } from 'react' // react version > 16.0
        
        var thisIsMyCopy = (
          <Fragment>
            <p>copy copy copy&nbsp;
            <strong>strong copy</strong>
            </p>
          </Fragment>
        )
        

        通过使用 '' 将值设置为一个字符串,React 无法知道它是一个 HTML 元素。您可以执行以下操作让 React 知道它是一个 HTML 元素 -

        1. 删除'' 就可以了
        2. 使用 &lt;Fragment&gt; 返回 HTML 元素。

        【讨论】:

        • 这没有回答问题。 thisIsMyCopy 的内容本身就是 JSX,而不是 HTML 字符串。所以你实际上是将 JSX 粘贴到 JSX 中。
        • 您也可以在 Preact 中找到 Fragments,但仅限于版本 X 及更高版本。
        • 我认为这是最好的方法,因为我们不必使用这种方法将其存储为字符串变量。还要记住,dangerouslySetInnerHTML 使用起来很危险,因为可以通过脚本标签注入恶意客户端代码:stackoverflow.com/a/42380982/6908282
        【解决方案9】:

        如果您不想要上述任何一项,请尝试Fragment

        在你的情况下,我们可以写

        import React, {useState, Fragment} from 'react'
        
        const thisIsMyCopy = Fragment('<p>copy copy copy <strong>strong copy</strong></p>')
        
        render: function() {
            return (
                <div className="content">{thisIsMyCopy}</div>
            );
        }
        

        如果您使用钩子想将其设置为任何条件的某个状态

        const [thisIsMyCopy, setThisIsMyCopy] = useState(<Fragment><p>copy copy copy <strong>strong copy</strong></p></Fragment>);
        

        【讨论】:

        • 您引用的库不是 React 的一部分,但在您的代码中,您从 React 导入 Fragment。你的 sn-p 抛出一个错误。
        【解决方案10】:

        您不需要任何特殊的库或“危险”属性。你可以只使用 React Refs 来操作 DOM:

        class MyComponent extends React.Component {
            
            constructor(props) {
                
                super(props);       
                this.divRef = React.createRef();
                this.myHTML = "<p>Hello World!</p>"
            }
            
            componentDidMount() {
                
                this.divRef.current.innerHTML = this.myHTML;
            }
            
            render() {
                
                return (
                    
                    <div ref={this.divRef}></div>
                );
            }
        }
        

        可以在此处找到工作示例:

        https://codepen.io/bemipefe/pen/mdEjaMK

        【讨论】:

        • 不错,你甚至可以使用this.divRef.current.outerHTML = this.myHTML;来避免多余的div。但是,createRef 需要 React 16.3,这并不总是一种选择,例如使用 SPFx for SharePoint 2019 on-prem...
        猜你喜欢
        • 2017-05-13
        • 2020-10-08
        • 1970-01-01
        • 2015-03-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多