没有包装div的情况下如何危险地使用SetInnerHTML?

时间:2018-12-08 12:49:20

标签: reactjs css-grid gatsby

我的HTML内容来自API(在本例中为Gatsby),因此我按照建议使用dangerouslySetInnerHTML。问题是,它与我的样式特别是与网格混乱。我有这样的html标记:

<article>
    <h2>Title of the post<h2>
    <small>Date of the post</small>
    <div dangerouslySetInnerHTML={{ __html: post.html }} />
</article>

<article>标签包含display: grid样式。但是该div中的所有内容都占用了宝贵的空间,因此很难设置样式(这也不是一个有用的div!)。所有重要的html都在里面,但是我想摆脱实际的<div>标签。有什么办法吗?

注意:我已经尝试直接{post.html},但是它是无法解码的已编码URI。

谢谢!

2 个答案:

答案 0 :(得分:1)

签出react docs for dangerouslySetInnerHTML

  

您可以直接从React设置HTML,但是您必须危险地键入SetInnerHTML并使用__html键传递对象...

因此,没有什么可以阻止您从graphql查询的不同部分形成自己的html字符串,如下所示:

const createFullPostMarkup = () => {
    return { __html: `<h2>Title of the post</h2><small>Date of the post</small>${ post.html }` }
}

然后将其稍后设置为您文章上的内部html:

<article dangerouslySetInnerHTML={createFullPostMarkup()} />

请记住,这只是一个带有__html key的对象。您可以在其中放任何东西。

注意:此公开feature request描述了我想您可能会追求的目标。对于您的用例,我认为上述解决方案非常有效。但是,如果您仍然不满意,请查看链接问题中的讨论。

答案 1 :(得分:0)

您也可以这样做:

/**
 * Load CSS file in parallel vs a blocking <link /> tag
 *
 * @param {string} fontUrl The raw font URL
 */
const LoadCSSFile = ({ fontUrl }) => {
  // hilariously bad hack to get around React's forced wrapper for dangerouslySetInnerHTML
  // @see https://github.com/facebook/react/issues/12014#issuecomment-434534770
  let linkStr = '</style>';
  linkStr += `<link rel="preload" href="${fontUrl}" as="style" onload="this.rel='stylesheet'" />`;
  linkStr += `<noscript><link rel="stylesheet" href="${fontUrl}"></noscript>`;
  linkStr += '<style>';

  return <style dangerouslySetInnerHTML={{ __html: linkStr }} />;
};

这将输出为:

<style></style>
<link ... />
<noscript><link ... /></noscript>
<style></style>

绝对不是最优雅的解决方案,但是它应该可以满足您的需要,直到React在片段上危险地支持SetInnerHTML为止。