【问题标题】:In React how to pass standard html as component?在 React 中如何将标准 html 作为组件传递?
【发布时间】:2019-12-11 19:12:00
【问题描述】:

我想编写一个接受包装器组件的 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?

【问题讨论】:

  • 在您的代码 sn-p 中什么不起作用?
  • @johnnypeter 我想将 h1 传递给 HOC,我不知道如何
  • 我认为TextLikeRender 不应该自动关闭,并且该组件应该容纳h1。在TextLikeRender 中,只需将其传递为this.props.children。所以 h1 会被 TextLikeRender 包裹起来。这就是你说的?

标签: javascript reactjs next.js


【解决方案1】:

一种可能的解决方案是在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' />

Demo is here

【讨论】:

    【解决方案2】:

    您的代码无需按原样更改(除了三元表达式中多余的分号)。只需将字符串 "h1" 作为 component 属性的值传递。

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

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

    上面的内容变成了这个纯 JavaScript:

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

    当上面的示例 TestComponent 被渲染时,React.createElement 将创建一个 React 元素,该元素渲染为“正常”&lt;div&gt; 元素。

    对于您的组件,无论在哪里使用 &lt;Wrapper&gt; 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 prop,并将其包装到使用它的代码中。而且,如果您可以将 any 值作为道具传递,那么完全避免 dangerouslySetInnerHTML 并将 ["This is ", &lt;br /&gt;, " Html"] 作为值传递会更好(更不用说更安全)了,如果这是可能的。

    【讨论】:

      猜你喜欢
      • 2017-09-06
      • 2019-06-04
      • 2020-02-15
      • 2020-08-20
      • 1970-01-01
      • 2018-08-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-03
      相关资源
      最近更新 更多