React-хуки
Импорт из os-detect/react. Требуется React 17+.
tsx
import { useOS, useIsWindows11 } from 'os-detect/react'useOS()
- Принимает: ничего
- Возвращает:
OS— вычисляется один раз черезuseState(() => getOS()), стабильно между рендерами
Синхронно возвращает текущую строку ОС.
tsx
function Banner() {
const os = useOS() // 'windows' | 'macos' | 'ios' | ...
return <p>Running on {os}</p>
}useIsWindows11()
- Принимает: ничего
- Возвращает:
boolean | null—null, пока определение выполняется
Запускает асинхронную проверку detectIsWindows11() внутри useEffect и обновляет состояние при получении результата.
tsx
function WindowsBadge() {
const isWin11 = useIsWindows11() // null → true | false
if (isWin11 === null) return <Spinner />
return <p>{isWin11 ? 'Windows 11' : 'Windows 10 или старше'}</p>
}SSR (Next.js)
useOS() вычисляет своё значение один раз через useState(() => getOS()), что выполняется во время рендера и на сервере тоже — при SSR это означает, что ОС сервера попадает в исходный HTML, а она может отличаться от клиентской, что может вызвать несовпадение при гидратации. Если контент, зависящий от ОС, должен точно совпадать на клиенте, отложите его до useEffect:
tsx
import { useEffect, useState } from 'react'
import { getOS } from 'os-detect'
import type { OS } from 'os-detect'
function OSBanner() {
const [os, setOS] = useState<OS | null>(null)
useEffect(() => {
setOS(getOS())
}, [])
if (!os) return null
return <p>OS: {os}</p>
}useIsWindows11() уже следует этому паттерну внутри себя (её результат разрешается внутри useEffect), поэтому ей этот обходной путь не нужен.