В этой серии статей мы отправимся в путешествие по миру пользовательских хуков React, открывая для себя их огромный потенциал для улучшения ваших проектов разработки. Сегодня мы сосредоточимся на хуке «useScript», одном из многих тщательно разработанных хуков, доступных в коллекции пользовательских хуков React.

GitHub

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: ссылка

Комментарии (4)


  1. KivApple
    13.08.2025 17:35

    Не хватает выгрузки скрипта (хотя бы удалить его из DOM) при отмонтировании компонента через cleanup функцию эффекта (не знаю как это работает с useAsync). Если компонент использующий скрипт отмонтируется и примонтируется (или изменится url), скрипт добавится дважды, трижды и т д. Это может быть нежелательное поведение. Как минимум утечка ресурсов, как максимум экземпляры скрипта могут конфликтовать.

    Альтернатива может быть завести глобальную Map результатов загрузки скриптов по url и если скрипт уже грузили раньше, не грузить его второй раз, а возвращать кешированный результат. Но надо обработать гонку, если useScript вызван повторно до окончания загрузки.


    1. JerryI
      13.08.2025 17:35

      Для меня кажется это странным грузить что то еще таким образом. Почему не динамический импорт? Бандл не уведичится, а просто чанк загрузится. Почти все либы уже поддерживают стандарт es.


      1. KivApple
        13.08.2025 17:35

        Автор привёл пример всяких внешних скриптов аналитики, социальных кнопок и прочих интеграций


    1. Able1991
      13.08.2025 17:35

      У меня такой хук называется useSdk =)

      а по загрузку несколько скриптов там просто так делать


      useSdk(id, url)


      const exists = document.getElementById(id);
      if (exists) return resolve();