Компонент Script¶
Компонент Script позволяет разработчикам определять приоритет загрузки сторонних скриптов, что экономит время и улучшает производительность.
Приоритет загрузки скрипта определяется с помощью пропа strategy , который принимает одно из следующих значений:
- beforeInteractive : предназначено для важных скриптов, которые должны быть загружены и выполнены до того, как страница станет интерактивной. К таким скриптам относятся, например, обнаружение ботов и запрос разрешений. Такие скрипты внедряются в первоначальный HTML и запускаются перед остальным JS
- afterInteractive : для скриптов, которые могут загружаться и выполняться после того, как страница стала интерактивной. К таким скриптам относятся, например, менеджеры тегов и аналитика. Такие скрипты выполняются на стороне клиента и запускаются после гидратации
- lazyOnload : для скриптов, которые могут быть загружены в период простоя. К таким скриптам относятся, например, поддержка чатов и виджеты социальных сетей
Script поддерживает встроенные скрипты со стратегиями afterInteractive и lazyOnload
встроенные скрипты, обернутые в Script , должны иметь атрибут id для их отслеживания и оптимизации
Примеры¶
Компонент Script не должен помещаться внутрь компонента Head или кастомного документа.
1 2 3 4 5 6 7 8 9 10 11 12
import Script from 'next/script'; export default function Home() return ( <> Script src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserverEntry%2CIntersectionObserver" strategy="beforeInteractive" /> /> ); >
1 2 3 4 5 6 7 8 9 10 11 12
import Script from 'next/script'; export default function Home() return ( <> Script src="https://connect.facebook.net/en_US/sdk.js" strategy="lazyOnload" /> /> ); >
Выполнение кода после полной загрузки страницы
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
import useState > from 'react'; import Script from 'next/script'; export default function Home() const [stripe, setStripe] = useState(null); return ( <> Script id="stripe-js" src="https://js.stripe.com/v3/" onLoad= => setStripe( stripe: window.Stripe('pk_test_12345'), >); >> /> /> ); >
1 2 3 4 5 6 7 8 9 10 11 12 13
import Script from 'next/script' Script id="show-banner" strategy="lazyOnload"> `document.getElementById('banner').classList.remove('hidden')`> /Script> // или Script id="show-banner" dangerouslySetInnerHTML= <__html: `document.getElementById('banner').classList.remove('hidden')` >> />
1 2 3 4 5 6 7 8 9 10 11 12 13 14
import Script from 'next/script'; export default function Home() return ( <> Script src="https://www.google-analytics.com/analytics.js" id="analytics" nonce="XUENAJFW" data-test="analytics" /> /> ); >
Как правильно в react запустить стороний script?
У меня есть необходимость в React приложение добавить чат поддержки сделанный на bitrix — это скрипт, который обычно добавляется в файл index.html. пример скрипта :
В данный момент я реализовал подключение следующим образом: создал компонент со скриптом
import React, < Component >from 'react' export default class Script extends Component < componentDidMount() < const s = document.createElement('script') // s.type = 'text/javascript' s.async = true s.innerHTML = "document.write('This is output by document.write()!')" s.src = 'https://someurl.js' + '?' + ((Date.now() / 60000) | 0) this.instance.appendChild(s) const h = document.getElementsByTagName('script')[0] h.parentNode.insertBefore(s, h) >render() < return (this.instance = el)> /> > >
и подключил его в корне приложения
import Script from './Script ' const App = () => < return( <> >) >
Это работает, но я думаю это решение не самое правильное. Если Кто-то может помочь правильно запустить внешний скрипт в реактивных приложениях (react, vue) буду очень признателен. заранее спасибо!!
Добавляем inline скрипт в React компонент: с Typekit
Для того чтобы добавить скрипт в компонент React, можете воспользоваться следующим кодом c использованием метода document.createElement в JavaScript:
Скопировать код
componentDidMount() < const script = document.createElement('script'); script.src = '//your-script-url.js'; document.body.appendChild(script); >
Такой подход дает возможность подгрузить скрипт в тело документа и немедленно начать его выполнение сразу после монтирования компонента.
Для функциональных компонентов подходит хук useEffect :
Скопировать код
import < useEffect >from 'react'; function useScript(url) < useEffect(() => < const script = document.createElement('script'); script.src = url; script.async = true; document.body.appendChild(script); return () =>< document.body.removeChild(script); >; >, [url]); >
Применив хук в виде useScript(‘//your-script-url.js’) , вы сможете внедрить скрипт внутрь своего компонента.
Стратегии вставки тегов script: подробный разбор
Добавление скрипта: подход React
React отлично подходит для создания чистого и модульного кода. Когда дело доходит до работы со скриптами, предпочтительно пользоваться собственными хуками или методами жизненного цикла для их инкапсуляции – это и есть настоящая абстракция.
С помощью componentDidMount для классовых компонентов мы можем добавить скрипт после рендера. В функциональных компонентах аналогичную роль выполняет useEffect .
Сила собственных хуков
Собственные хуки – это мощный инструмент для реализации решений, которые просто интегрируются и тестируются, и с помощью которых можно легко загружать скрипты в разные компоненты React.
Встроенные скрипты или модули из npm?
Перед тем, как применить внешние скрипты, всегда проверяйте, нет ли необходимой функциональности среди npm-пакетов. Это обеспечит безопасность и совместимость с экосистемой React.
Заключительные рекомендации и передовые практики
Управление метаинформацией страницы с помощью React Helmet
React Helmet – это простой и безопасный способ динамического добавления скриптов. Он упрощает управление разметкой head и облегчает удаление элементов.
Важность удаления скриптов
В useEffect функция очистки избавит от скрипта при размонтировании компонента, предотвращая его повторное добавление и возможные утечки памяти.
Понимание и обход рисков безопасности
Для сокращения рисков XSS используйте инструменты санитизации, вроде react-safe . Старайтесь избегать использования методов типа dangerouslySetInnerHTML , которые могут существенно увеличить уязвимость приложений.
Асинхронная загрузка скриптов
Держите в уме возможность асинхронной загрузки с использованием атрибута async . Это позволит вам не блокировать основной поток выполнения. Кроме того, при возникновении ошибок применяйте try-catch для их надежного обработчика.
Визуализация
Рассмотрите ваш React-компонент как стену из кирпичей, где добавляемый скрипт – это новый кирпич. Чтобы пристроить его, вам потребуется инструмент в виде хука:
Как добавить script в react
Расширения для в React в настоящее время доступны только в канале React canary и экспериментальном канале. В стабильных релизах React работает только как встроенный в браузер HTML-компонент. Подробнее о каналах выпуска React здесь.
script> alert("hi!") /script>
Описание¶
Чтобы добавить в документ встроенные или внешние скрипты, отобразите встроенный в браузер компонент . Вы можете рендерить из любого компонента, и React в определенных случаях поместит соответствующий элемент DOM в голову документа и удалит дублирование идентичных скриптов.
script> alert("hi!") /script> script src="script.js" />
Параметры
У него должны быть либо children , либо проп src .
- children : строка. Исходный код встроенного скрипта.
- src : строка. URL-адрес внешнего скрипта.
Другие поддерживаемые пропсы:
- async : булево. Позволяет браузеру отложить выполнение скрипта до тех пор, пока не будет обработана остальная часть документа — предпочтительное поведение для повышения производительности.
- crossOrigin : строка. Политика CORS, которую следует использовать. Возможные значения: anonymous и use-credentials .
- fetchPriority : строка. Позволяет браузеру ранжировать скрипты по приоритету при одновременной выборке нескольких скриптов. Может быть «high» , «low» или «auto» (по умолчанию).
- integrity : строка. Криптографический хэш скрипта для проверки его подлинности.
- noModule : булево. Отключает скрипт в браузерах, поддерживающих ES-модули, и позволяет использовать запасной скрипт в браузерах, которые этого не делают.
- nonce : строка. Криптографический nonce для разрешения ресурса при использовании строгой политики безопасности содержимого.
- referrer : строка. Указывает какой заголовок Referer отправить при выборке скрипта и любых ресурсов, которые скрипт в свою очередь берет.
- type : строка. Указывает, является ли скрипт классическим скриптом, ES-модулем или import map.
- onError : функция. Вызывается, когда скрипт не загружается.
- onLoad : функция. Вызывается, когда скрипт завершает загрузку.
Пропсы, которые не рекомендуется использовать с React:
- blocking : строка. Если установлено значение «render» , это указывает браузеру не рендерить страницу до тех пор, пока не будет загружен лист скриптов. React обеспечивает более тонкий контроль с помощью Suspense.
- defer : строка. Запрещает браузеру выполнять скрипт до окончания загрузки документа. Не совместим с потоковыми компонентами, рендеримыми сервером. Вместо этого используйте параметр async .
Специальное поведение рендеринга¶
React может перемещать компоненты в документа, де-дублировать идентичные скрипты и приостанавливать загрузку скрипта.
Для того, чтобы принять это поведение, укажите свойства src и async= . React будет дедублировать скрипты, если у них одинаковый src . Свойство async должно быть истинным, чтобы скрипты можно было безопасно перемещать.
Если вы передадите любой из параметров onLoad или onError , то никакого особого поведения не будет, поскольку эти параметры указывают на то, что вы управляете загрузкой скрипта вручную внутри вашего компонента.
Это особое обращение сопровождается двумя оговорками:
- React будет игнорировать изменения пропсов после рендеринга скрипта. (React выдаст предупреждение в процессе разработки, если это произойдет).
- React может оставить скрипт в DOM даже после того, как компонент, который его отрисовал, будет размонтирован. (Это не имеет никакого эффекта, так как скрипты выполняются только один раз, когда их вставляют в DOM).
Использование¶
Рендеринг внешнего скрипта¶
Если компонент зависит от определенных скриптов для корректного отображения, вы можете отобразить внутри компонента.
Если вы укажете свойства src и async , ваш компонент приостановится на время загрузки скрипта. React будет де-дублировать скрипты с одинаковым src , вставляя в DOM только один из них, даже если его рендерят несколько компонентов.
App.js ShowRenderedHTML.js CodeSandbox
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
import ShowRenderedHTML from './ShowRenderedHTML.js'; function Map( lat, long >) return ( <> script async src="map-api.js" /> div id="map" data-lat=lat> data-long=long> /> /> ); > export default function Page() return ( ShowRenderedHTML> Map /> /ShowRenderedHTML> ); >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
import renderToStaticMarkup > from 'react-dom/server'; import formatHTML from './formatHTML.js'; export default function ShowRenderedHTML( children >) const markup = renderToStaticMarkup( html> head /> body>children>/body> /html> ); return ( <> h1>Rendered HTML:/h1> pre>formatHTML(markup)>/pre> /> ); >
Когда вы хотите использовать скрипт, может быть полезно вызвать функцию preinit. Вызов этой функции может позволить браузеру начать выборку скрипта раньше, чем если бы вы просто отобразили компонент , например, отправив ответ HTTP Early Hints response.
Рендеринг встроенного скрипта¶
Чтобы включить встроенный скрипт, отобразите компонент с исходным кодом скрипта в качестве его дочерних элементов. Встроенные скрипты не дублируются и не перемещаются в документ , а поскольку они не загружают никаких внешних ресурсов, они не приведут к приостановке работы вашего компонента.
App.js ShowRenderedHTML.js CodeSandbox
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
import ShowRenderedHTML from './ShowRenderedHTML.js'; function Tracking() return script>ga('send', 'pageview');/script>; > export default function Page() return ( ShowRenderedHTML> h1>My Website/h1> Tracking /> p>Welcome/p> /ShowRenderedHTML> ); >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
import renderToStaticMarkup > from 'react-dom/server'; import formatHTML from './formatHTML.js'; export default function ShowRenderedHTML( children >) const markup = renderToStaticMarkup( html> head /> body>children>/body> /html> ); return ( <> h1>Rendered HTML:/h1> pre>formatHTML(markup)>/pre> /> ); >