【问题标题】:How to use <Link /> component inside dangerouslySetInnerHTML如何在危险的SetInnerHTML中使用<Link />组件
【发布时间】:2019-06-18 21:14:02
【问题描述】:

目前我的一个组件中有这个:

{someObject.map(obj => (
    <div
        dangerouslySetInnerHTML={{
            __html: obj.text
        }}
    />
))}

基本上,我映射到另一个文件上的someObject。结构是这样的:

export default someObject = [
      {
         obj: "<p>Some text 1.</p>"
      },
      {
         obj: "<p>Some text 2.</p>"
      }
    ]

我只是为了演示而简化了内容。但是,我遇到了一个问题,因为我需要在其中一项中使用&lt;Link /&gt; 组件。如:

export default someObject = [
    {
        obj: "<p>Some text 1.</p>"
    },
    {
        obj: "<p>Some text 2.</p>"
    },
    {
        obj: "<p>Some text 2 and <Link to="/someroute">link</Link>.</p>"
    }
]

但是,它不起作用,因为整个 &lt;p&gt;&lt;/p&gt; 标记都包含在 dangerouslySetInnerHTML 中。

我可以只使用普通的&lt;a&gt;&lt;/a&gt; 标记作为链接,但这似乎不是一个好的解决方案,因为整个应用程序会重新加载,而不是仅仅转到另一条路线。

还有哪些其他选项可以完成这项工作?

【问题讨论】:

  • 为什么不把它们转换成简单的 JSX sn-ps 并像普通的 react 组件子组件一样使用它们?
  • @Derek 可以详细说明一下吗?举个例子?
  • @Derek 没关系,我明白你的意思。意识到我实际上可以使用 JSX 作为对象的值。

标签: javascript reactjs react-router react-router-dom


【解决方案1】:

为什么不直接将对象导出为 jsx 对象?我认为使用dangerouslySetInnerHTML 是一种不好的做法,它可能会导致XSS 攻击。

const someObject = [
  {
    obj: <p>Some text 1.</p>
  },
  {
    obj: <p>Some text 2.<a href="https://google.com">google</a></p>
  }
]
class App extends React.Component {
  render(){ 
    return (
    <div className="App">
      <h1>Hello world</h1>
      <h2>Jsx object goes here {someObject[1].obj}</h2>
    </div>
  )};
}

const rootElement = document.getElementById("container");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.2/react-dom.min.js"></script>
<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

【讨论】:

  • 是的,我意识到我实际上可以做到这一点,而不是将所有内容都包装在一个字符串中。
【解决方案2】:
  • 有两种方法可以解决这个问题:

第一种方式:

这就像一种更通用的方法,您可以使用它来选择您的代码。 尝试使用这个库 (https://github.com/tasti/react-linkify/)

这是组件的更简单形式:

import React, {PropTypes} from 'react';
import Linkify from 'react-linkify';

export default class TextWithLink extends React.Component {
    constructor(props) {
      super(props);
    }

    render() {
      let text = this.props.text;
      if(this.props.showLink) {
        text = <Linkify properties={{target: '_blank', rel: "nofollow   noopener"}}>{text}</Linkify>
      }
      return (<div>{text}</div>);
    }
}

第二种方式:

如果你想创建一个超链接 (&lt;a&gt;),你应该有一个构建元素并返回结果的函数。

例子:

list = {
  text: 'hello world',
  link: 'www.facebook.com'
}

渲染函数可能是这样的:

buildLink() {
   return(
      <p>
        {list.text}. <a href={list.link}>{list.link}</a>
      </p>
    );
}

render() {
   return (this.buildLink());
}

【讨论】:

    【解决方案3】:
    export default someObject = [
        {
            obj: "<p>Some text 1.</p>"
        },
        {
            obj: "<p>Some text 2.</p>"
        },
        {
            obj: linkto('/someroute')
        }
    ]
    

    linkto 将解决您的问题。

    【讨论】:

    • 在 ${linkto('/someroute') 中的何处插入“链接”文本?
    • 请先试试这段代码 ``` obj: linkto('/login') ``
    猜你喜欢
    • 1970-01-01
    • 2018-04-30
    • 2021-07-24
    • 1970-01-01
    • 2019-04-26
    • 1970-01-01
    • 2021-01-19
    • 1970-01-01
    相关资源
    最近更新 更多