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