简体   繁体   English

无法在 Reactjs 中有条件地渲染 HTML UL

[英]Unable to render HTML UL conditionally in Reactjs

I am trying to render a list not more than 5 conditionally by checking the number of items and a "more" button.我试图通过检查项目数量和“更多”按钮来有条件地呈现不超过 5 个的列表。 When I pass in 5 li items it renders it as text instead of HTML elements.当我传入 5 li项目时,它会将其呈现为文本而不是 HTML 元素。

let sectionCount = 0;
const MAX_COUNT_TO_SHOW = 5;
const getAssets = data => {
  let assets = "<ul>";
  let index = 0;
  for (var improperAsset of data) {
    if (index < MAX_COUNT_TO_SHOW) {
      assets += "<li>" + improperAsset + "</li>";
    }
    index++;
  }
  assets += "</ul>";
  console.log(assets);
  return <div>{assets}</div>;
};
const getSectionBody = info => {
  if (info.ic > MAX_COUNT_TO_SHOW) {
    return (
      <div>
        <p>
          {info.name} should be named as <b>{info.label}</b>
        </p>
        <i>
          <b>{info.ic}</b> instance(s) located for improper naming
        </i>
        {getAssets(info.data)}
        <div style={{ color: "blue" }} onClick={() => openDialog(info["data"])}>
          Show More
        </div>
      </div>
    );
  } else {
    return (
      <div>
        <p>
          {info.name} should be named as <b>{info.label}</b>
        </p>
        <i>
          <b>{info.ic}</b> instance(s) located for improper naming
        </i>
        {getAssets(info.data)}
      </div>
    );
  }
};

const isCollapsible = () => {
  if (sectionCount == 0) {
    sectionCount++;
    return true;
  } else {
    return false;
  }
};

const openDialog = useCallback(
  data => {
    setAssetsInfo(data);
    setClosed(false);
  },
  [setClosed]
);

return (
  <div style={{ margin: "0px 0px 10px 10px" }}>
    <Container fluid style={{ padding: "0px" }}>
      <Row>
        <Col sm={3}>
          <Button variant="primary">Customize</Button>
        </Col>
      </Row>
    </Container>
    <Panel title={""}>
      {myData.map(info => {
        return (
          <Section
            key={uuid()}
            title={info.name + " " + info.tc + " (" + info.ic + ")"}
            collapsible
            expanded={isCollapsible()}
            initialCollapsed={true}
          >
            <Container fluid={true}>{getSectionBody(info)}</Container>
          </Section>
        );
      })}

      <MainDialog
        assetsInfo={assetsInfo}
        closed={closed}
        setClosed={setClosed}
      ></MainDialog>
    </Panel>
  </div>
);

在此处输入图像描述

It is because you are passing in the data as a string rather than actual JSX elements.这是因为您将数据作为字符串而不是实际的 JSX 元素传递。 While you CAN do this it is very close to never being a good idea.虽然你可以做到这一点,但它几乎不是一个好主意。

There are many ways to skin a cat but consider something like the following给猫剥皮的方法有很多,但请考虑以下方法

const getAssets = data => {
  return 
    (
        <div>
            <ul>
              {data.slice(0,5).map((improperAsset) => (<li>{improperAsset}</li>))}
            </ul>
        </div>
    );
};

If your "improperAsset" contains html and needs to be rendered as such, I would consider either moving these improper assets into separate components or using a library to handle HTML parsing otherwise you run serious risk of introducing cross site scripting vulnerabilities into your site.如果您的“不正确资产”包含 html 并且需要这样渲染,我会考虑将这些不正确的资产移动到单独的组件中或使用库来处理 HTML 解析,否则您将面临将跨站点脚本漏洞引入您的站点的严重风险。

FYI, that's how the minimal reproducible example may look like in that case. 仅供参考,这就是在这种情况下最小可重现示例的样子。 If you want to do that this way you can use dangerouslySetInnerHTML but as mentioned earlier, this may expose your code to cross-site scripting .如果您想这样做,您可以使用dangerouslySetInnerHTML但如前所述,这可能会将您的代码暴露给跨站点脚本

return <div dangerouslySetInnerHTML={{ __html: assets }}></div>;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM