Внешний сценарий должен изменить InnerHTML компонента React

Мой вопрос

У меня есть встроенная форма React который импортируется на php стр. Форма является единственной частью страницы, встроенной в React. У меня нет контроля над другими элементами на странице. Мне нужно иметь возможность загрузить "Печать" в форму от Digicert для проверки SSL-сертификата на сайте. Моя форма будет использоваться в нескольких объектах, принадлежащих моей компании, поэтому мне нужно пройти props к Seals компонент, который устанавливает конкретный сайт id на форме. Digicert проверяет этот идентификатор вместе с некоторыми другими данными для асинхронной загрузки собственного внешнего сценария, который добавляет изображение печати в виде 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 успешно менял innerHTML div с жестко-закодированным значением.

... но при создании динамического

Тем не менее, мне нужно сделать эту динамику, чтобы принимать разные значения идентификаторов на основе реквизитов, переданных в форму. Когда я добавляю динамическое значение, я думаю, что 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>
   )
}

Кто-нибудь может придумать обходной путь? Я правильно диагностирую эту проблему? Какие-либо предложения?

0 ответов

Мне следовало бы лучше задокументировать свой первоначальный ответ. Я не могу вспомнить, какую версию React я использовал. Однако ответ основан на использованииrefs.

См.: https://reactjs.org/docs/refs-and-the-dom.html И: https://reactjs.org/docs/integrating-with-other-libraries.html

Оба источника добавляют к решению. Во-первых, используяReact.createRef, это создает ссылку на DOM, которая может использоваться, например, внешними библиотеками. Во-вторых, гарантируя, что компонент не обновляется, это означает, что React должен оставить его в покое при повторном рендеринге:

Самый простой способ избежать конфликтов - предотвратить обновление компонента React. Вы можете сделать это, отрисовав элементы, которые React не имеет смысла обновлять. Источник

В этом случае я хочу иметь возможность динамически отображать конкретную печать DigiCert на основе originстраницы. Это нужно сделать только один раз, и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 к элементу, к которому обращается внешний скрипт, и я запомнил компонент, поэтому он должен изменяться только при изменении реквизита (и, следовательно, я никогда не отправляю ему никаких реквизитов!):

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 вызов функции, похоже, решил эту проблему.

Другие вопросы по тегам