在 React 中如何将标准 html 作为组件传递?



我想写一个接受包装器组件的 HOC ,但想像这样为内部 html 传递标准元素。

type TextLike = string | {type,content}
const TextLikeRender = ({value,component:Wrapper})=>{
return (
value.type==='html'?
<Wrapper dangerouslySetInnerHTML={{__html: value.content}}/>:
<Wrapper>{value}</Wrapper>;
)
}
// use like this
<TextLikeRender value={{type:'html',content:'This is <br/> Html'}} component={/* how to reference h1 element */XXXX.h1} />

我想将h1作为 TextLikeRender 的组件传递,如何引用 h1?

一种可能的解决方案是在TextLikeRender中使用React.createElement。这样,您可以将组件作为字符串传递。

export const TextLikeRender = ({ value, component:Wrapper })=> {
return value && value.type==='html' ?
React.createElement (Wrapper, { dangerouslySetInnerHTML: {__html: value.content} }) :
React.createElement (Wrapper, {}, value && value.content)
}

用法

<TextLikeRender value={{type:'html',content:'This is <br/> Html'}} component='h1' />

演示在这里

无需按原样更改代码(除了三元表达式中的无关分号(。只需将字符串"h1"作为componentprop 的值传递即可。

JSX 只是用于调用React.createElement的语法糖。如果 JSX 标签以大写字母开头,则保持原样并作为第一个参数传递给React.createElement,否则如果标签名称以小写字母开头,它将变成字符串,然后作为第一个参数传递。

function TestComponent(){
return <div>Testing!</div>;
}

上面变成了这个普通的JavaScript:

function TestComponent(){
return React.createElement("div", null, "Testing!");
}

当上面TestComponent示例呈现时,React.createElement将创建一个渲染为"普通"<div>元素的 React 元素。

对于您的组件,无论在哪里使用<Wrapper>JSX 标记,Wrapper都将作为第一个参数传递给React.createElementWrapper的值可以是 React 组件,但它也可以只是一个字符串,例如"div"。因此,您所要做的就是像这样使用代码:

const TextLikeRender = ({ value, component: Wrapper }) => {
if (value.type === "html") {
return <Wrapper dangerouslySetInnerHTML={{__html: value.content}} />;
} else {
return <Wrapper>{value}</Wrapper>;
}
}
<TextLikeRender value={{type: 'html', content: 'This is <br/> Html'}} component="h1" />

最后 — 这与问题无关,但是像这样的组件可能会更好,因为typevalue都是单独的道具,更好的是不要让TextLikeRender拿一个component道具,并将其包装留给使用它的代码。而且,鉴于您可以将任何值作为道具传递,如果可能的话,最好(更不用说更安全,更安全(完全避免dangerouslySetInnerHTML["This is ", <br />, " Html"]作为值传递。

最新更新