将 HTML 传递给自定义组件
Posted
技术标签:
【中文标题】将 HTML 传递给自定义组件【英文标题】:Pass HTML into custom Component 【发布时间】:2021-12-28 11:38:45 【问题描述】:我创建了一个自定义组件来简单地在 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> </div>
else
return null
;
export default CardContainer;
但是,我现在想开始将一些 html 元素传递给组件,这样我就可以通过使文本变为粗体或将部分字符串包装在 span 中并添加一个 css 类来突出显示文本部分它。
目前,将 html 添加到 content 属性只会导致 this 显示为文字字符串。这显然是由于“内容”被声明为字符串。
显示 html 的解决方案是简单地更改接口中的类型声明吗?如果是这样,该怎么办?还是需要更复杂的解决方案?
谢谢。
【问题讨论】:
我不知道 ionic,但是你不能用 React 的children
属性来传递它们吗?- reactjs.org/docs/composition-vs-inheritance.html#containment
这能回答你的问题吗? How to safely render html in react?
@Dilshan,感谢您的提示。奇怪的是,这对我来说是一个新概念。我不确定它在这种情况下是否真的有效,但它确实帮助我处理了我遇到的另一个问题。
@E.Maggini 我不确定是不是。我不需要清理,因为“html”是系统生成的。我只需要能够将传入的字符串显示为 html 而不是字符串。因此,例如将其传递给组件“HELLO”,它会显示为 html,而不是显示为文字字符串。谢谢。
@E.Maggini 我已经考虑了这些信息,否则我将无法说; “我不确定它是不是”。根据blog.logrocket.com/…,您在使用 dangerouslySetInnerHTML 时不需要进行清理。此外,我从自定义组件本身返回 html,没有进行任何清理。因此,我的回应是; “我不确定是不是”。
【参考方案1】:
来自 cmets 中的重复答案:
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> </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 值以满足您的需要
【讨论】:
谢谢,这很有帮助。我试试看。 不幸的是,这给了我在条件语句中生成的标记字符串中显示变量的各种问题。另外,我很困惑为什么我的 if/else 字符串显示没有经过清理,但是你说 html 必须在 react 可以显示之前进行清理。 我已经设法进行了一些更改,以使我更接近最终结果。谢谢。【参考方案2】:将我的所有 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> </div>
else
return null
;
export default CardContainer;
【讨论】:
以上是关于将 HTML 传递给自定义组件的主要内容,如果未能解决你的问题,请参考以下文章
如何将 navigator.pop 传递给自定义反应原生组件