将 HTML 传递给自定义组件

Pass HTML into custom Component

我创建了一个自定义组件来简单地在 IonCardContent 中布置内容。到目前为止,这非常适合我的需求:

interface ContainerProps {
    position?: string;
    content?: string,
    colour?: string;
    custClass?: string;
}

const CardContainer: React.FC<ContainerProps> = ({ position = "right", content = "n/a", colour = "", custClass = "" }) => {
    
    if ( position.trim().toLowerCase() === "right" ) {
        return <><div className={"ion-float-right " + custClass} >{content}</div><div className="clear-right"></div></>
    } else if ( position.trim().toLowerCase() === "left" ) {
        return <div className={"ion-float-left " + custClass}>{content}</div> 
    } else if ( position.trim().toLowerCase() === "full" ) {
        return <div className={""  + custClass}>{content}</div>
    } else if ( position.trim().toLowerCase() === "empty" ) { 
        return <div className={""  + custClass}>&nbsp;</div> 
    } else {
        return null
    }  
};

export default CardContainer;

但是,我现在想开始将一些 html 元素传递给组件,这样我就可以做一些事情,比如通过将文本加粗或将部分字符串包装在一个范围内来突出显示文本部分并向其添加 css class。

目前,将 html 添加到内容属性只会导致其显示为文字字符串。这显然是由于“内容”被声明为字符串。

显示 html 的解决方案是简单地更改接口中的类型声明吗?如果是这样,怎么办?还是需要更复杂的解决方案?

谢谢。

来自评论中的重复答案:

import sanitizeHtml from 'sanitize-html';

const MyComponent = () => {
  dirty = '<a href="my-slug" target="_blank" onClick="evil()">click</a>';
  const clean = sanitizeHtml(dirty, {
    allowedTags: ['b', 'i', 'em', 'strong', 'a'],
    allowedAttributes: {
      a: ['href', 'target']
    }
  });
  return (
    <div 
      dangerouslySetInnerHTML={{__html: clean}}
    />
  );
};

因此

import sanitizeHtml from 'sanitize-html';

interface ContainerProps {
    position?: string;
    content?: string,
    colour?: string;
    custClass?: string;
}

 const CardContainer: React.FC<ContainerProps> = ({ position = "right", 
 content = "n/a", colour = "", custClass = "" }) => {

const myHTML = null;
    
    if ( position.trim().toLowerCase() === "right" ) {
        myHTML = '<div className={"ion-float-right " + custClass} >{content}</div><div className="clear-right"></div>'
    } else if ( position.trim().toLowerCase() === "left" ) {
        myHTML = '<div className={"ion-float-left " + custClass}>{content}</div>' 
    } else if ( position.trim().toLowerCase() === "full" ) {
        myHTML = '<div className={""  + custClass}>{content}</div>'
    } else if ( position.trim().toLowerCase() === "empty" ) { 
        myHTML = '<div className={""  + custClass}>&nbsp;</div>'
    }

 const clean = sanitizeHtml(myHTML, {
    allowedTags: ['b', 'i', 'em', 'strong', 'a'],
    allowedAttributes: {
      a: ['href', 'target']
    }
  });
  return (
    <div 
      dangerouslySetInnerHTML={{__html: clean}}
    />
  );
};

export default CardContainer;

您当然需要调整 allowedTags 和 allowedAttribute 值以满足您的需要

将我的所有 html 输出加上通过变量传入的动态内容传递到 santizer 中意味着变量要么被剥离,要么它们的调用显示为文字标记。

因此,有必要清理包含传递给组件的 html 内容的变量。

import React from 'react';
import './CardContainer.css';
import sanitizeHtml from 'sanitize-html';

interface ContainerProps {
    position?: string;
    content?: string,
    colour?: string;
    custClass?: string;
}

const CardContainer: React.FC<ContainerProps> = ({ position = "right", content = "n/a", colour = "", custClass = "" }) => {
    
    const clean = sanitizeHtml(content, {
        allowedTags: ['b', 'i', 'em', 'strong', 'a', 'div', 'span'],
        allowedAttributes: {
          a: ['href', 'target'],
          div: ['class', 'className'],
          span: ['style', 'class', 'className']
        }
    });
    


    if ( position.trim().toLowerCase() === "right" ) {
        return <><div className={"ion-float-right " + custClass} dangerouslySetInnerHTML={{__html: clean}}/><div className="clear-right"></div></>
    } else if ( position.trim().toLowerCase() === "left" ) {
        return <div className={"ion-float-left " + custClass} dangerouslySetInnerHTML={{__html: clean}}/>
    } else if ( position.trim().toLowerCase() === "full" ) {
        return <div className={""  + custClass} dangerouslySetInnerHTML={{__html: clean}}/>
    } else if ( position.trim().toLowerCase() === "empty" ) { 
        return <div className={""  + custClass}>&nbsp;</div> 
    } else {
        return null
    }  
};

export default CardContainer;