В этой серии статей мы отправимся в путешествие по миру пользовательских хуков React, открывая для себя их огромный потенциал для улучшения ваших проектов разработки. Сегодня мы сосредоточимся на хуке «useScript», одном из многих тщательно разработанных хуков, доступных в коллекции пользовательских хуков React.
import useAsync from "../useAsync/useAsync"
export default function useScript(url) {
return useAsync(() => {
const script = document.createElement("script")
script.src = url
script.async = true
return new Promise((resolve, reject) => {
script.addEventListener("load", resolve)
script.addEventListener("error", reject)
document.body.appendChild(script)
})
}, [url])
}
Одним из существенных преимуществ useScript является его способность обрабатывать загрузку скрипта асинхронно. Установив для атрибута async скрипта значение true, вы гарантируете, что он не будет блокировать рендеринг вашего приложения. Это повышает производительность и удобство работы с пользователем, особенно при работе с большими скриптами или при медленном сетевом подключении.
useScript можно использовать в различных сценариях. Например, вы можете загружать внешние библиотеки, такие как jQuery, что позволяет использовать его мощные функциональные возможности, не увеличивая объем вашего пакета. Кроме того, вы можете загрузить аналитические скрипты, виджеты социальных сетей или любые другие скрипты, необходимые для динамического поведения вашего приложения.
import useScript from "./useScript"
export default function ScriptComponent() {
const { loading, error } = useScript(
"https://code.jquery.com/jquery-3.6.0.min.js"
)
if (loading) return <div>Loading</div>
if (error) return <div>Error</div>
return <div>{window.$(window).width()}</div>
}
В приведенном выше примере мы видим, как useScript используется в компоненте ScriptComponent. Модуль useScript вызывается с использованием URL-адреса библиотеки jQuery в качестве аргумента. Хук возвращает состояния загрузки и ошибки, которые могут быть использованы для отображения индикатора загрузки или сообщения об ошибке соответственно. Как только скрипт успешно загружен, компонент отображает текущую ширину окна с помощью jQuery.
Full Version | React Custom Hooks: ссылка
KivApple
Не хватает выгрузки скрипта (хотя бы удалить его из DOM) при отмонтировании компонента через cleanup функцию эффекта (не знаю как это работает с useAsync). Если компонент использующий скрипт отмонтируется и примонтируется (или изменится url), скрипт добавится дважды, трижды и т д. Это может быть нежелательное поведение. Как минимум утечка ресурсов, как максимум экземпляры скрипта могут конфликтовать.
Альтернатива может быть завести глобальную Map результатов загрузки скриптов по url и если скрипт уже грузили раньше, не грузить его второй раз, а возвращать кешированный результат. Но надо обработать гонку, если useScript вызван повторно до окончания загрузки.
JerryI
Для меня кажется это странным грузить что то еще таким образом. Почему не динамический импорт? Бандл не уведичится, а просто чанк загрузится. Почти все либы уже поддерживают стандарт es.
KivApple
Автор привёл пример всяких внешних скриптов аналитики, социальных кнопок и прочих интеграций
Able1991
У меня такой хук называется useSdk =)
а по загрузку несколько скриптов там просто так делать
useSdk(id, url)
const exists = document.getElementById(id);
if (exists) return resolve();