外部脚本需要更改React组件的InnerHTML

时间:2019-04-08 22:49:52

标签: reactjs innerhtml react-props digicert

我的问题

我有一个内置于React的表单,该表单正在导入到php页面上。表单是React中内置页面的唯一部分。我无法控制页面上的其他元素。我需要能够在Digicert的表单上加载“印章”,以在站点上验证SSL证书。我的表单将用于公司所有的多个属性,因此我需要将props传递到Seals组件,该组件在表单上设置了特定于站点的idDigicert验证此id以及其他数据以异步加载其自己的外部脚本,该脚本将innerHTML的印章图像与预期的div添加到id以及弹出脚本到图像。

正在运行

在表单的早期版本中,我对id进行了硬编码,Component是一个无状态功能组件,甚至无法处理道具。见下文:

function Seals() {
  return (
    <div id="seals">
      <div id="hard-coded-value" data-language="en">
        <a href="https://www.digicert.com/ev-multi-domain-ssl.htm"></a>
      </div>
        {...other seals}
    </div>
   )
}

export default Seals

外部digicert脚本已使用硬编码值成功更改了div的innerHTML

...但是,当进行动态设置时,它会失败

但是,我需要使其动态变化,以便根据传递给表单的道具接受不同的id值。当添加动态值时,我认为React阻止了更新或只是将其还原为原始版本,因为它正在扩展组件。许多道具都传递给该表单,因此可能需要对其进行多次评估,并且innerHTML更改将被覆盖。我实际上让印章在刷新后出现一次,但无法使其重复。

使用id属性查看更新的组件:

function Seals({id}) {
  return (
    <div id="seals">
      <div id={id} data-language="en">
        <a href="https://www.digicert.com/ev-multi-domain-ssl.htm"></a>
      </div>
        {...other seals}
    </div>
   )
}

有人能想到解决方法吗?我是否可以正确诊断此问题?有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我应该更好地记录我的原始答案。我不记得我使用的是哪个版本的React。但是,答案基于使用refs

请参阅:https://reactjs.org/docs/refs-and-the-dom.html 并且:https://reactjs.org/docs/integrating-with-other-libraries.html

两个来源都添加到解决方案中。首先,通过使用React.createRef,这将创建对DOM的引用,例如,外部库可以使用该DOM。其次,通过确保Component不更新,这意味着React应该在重新渲染时将其保留:

  

避免冲突的最简单方法是防止React组件更新。您可以通过渲染React没有理由更新的元素来做到这一点。 Source

在这种情况下,我希望能够基于页面的origin动态呈现特定的DigiCert印章。这仅需要渲染一次,seals.min.js是DigiCert加载的异步脚本,用于验证域上的SSL,并在DOM占位符中向页面添加小部件。

我创建了一个保存重要的certs数据的对象:

const certs = {
  "https://www.origin1.com": {
    id: "DigiCertClickID_PRIVATE_CODE",
    href: "https://www.digicert.com/ev-multi-domain-ssl.htm",
  },
  "https://another.origin.com": {
    id: "DigiCertClickID_PRIVATE_CODE",
    href: "https://www.digicert.com/ssl-certificate.htm",
  },
};

DigiCert组件中,我为外部脚本访问的元素创建了一个ref,并记住了该组件,因此它仅应在props更改时更改(因此,我永远不会发送它道具!):

import React, { createRef, memo } from 'react'

const DigiCert = memo(() => {
  const { origin } = window.location;
  const cert = certs[origin];
  const digicertSeal = React.createRef();
  return (
    cert && (
      <div
          id={cert.id}
          data-language="en"
          className="seals__seal"
          ref={digicertSeal}
        >
        <a
          className="seals__seal--link"
          href={cert.href}
          aria-label="Digicert Seal"
        >
          {/* DigiCert.com */}
        </a>
      </div>
    )
  );
});

此组件的父级也不应更改,并且我也谨记这一点。

const Seals = ({ style = {} }) => (
  <div id="seals" style={style}>
    <DigiCert />
  </div>
)

export default memo(Seals);

ref属性和memo函数调用的组合似乎已纠正了此问题。