CSS-in-JS
Предупреждение: Библиотеки CSS-in-JS, требующие выполнения JavaScript в рантайме, в настоящее время не поддерживаются в серверных компонентах. Использование CSS-in-JS с новыми функциями React, такими как серверные компоненты и потоковая передача, требует от авторов библиотек поддержки последней версии React, включая конкурентный рендеринг.
Мы работаем с командой React над API верхнего уровня для обработки CSS и JavaScript-ресурсов с поддержкой серверных компонентов React и потоковой архитектуры.
Следующие библиотеки поддерживаются в клиентских компонентах в директории app
(в алфавитном порядке):
kuma-ui
@mui/material
pandacss
styled-jsx
styled-components
style9
tamagui
tss-react
vanilla-extract
Следующие библиотеки в настоящее время работают над поддержкой:
Полезно знать: Мы тестируем различные библиотеки CSS-in-JS и будем добавлять больше примеров для библиотек, поддерживающих функции React 18 и/или директорию
app
.
Если вы хотите стилизовать серверные компоненты, мы рекомендуем использовать CSS Modules или другие решения, которые выводят CSS-файлы, такие как PostCSS или Tailwind CSS.
Настройка CSS-in-JS в app
Настройка CSS-in-JS — это трёхэтапный процесс, который включает:
- Реестр стилей для сбора всех CSS-правил во время рендеринга.
- Новый хук
useServerInsertedHTML
для вставки правил перед любым контентом, который может их использовать. - Клиентский компонент, который оборачивает ваше приложение с реестром стилей во время первоначального серверного рендеринга.
styled-jsx
Использование styled-jsx
в клиентских компонентах требует версии v5.1.0
. Сначала создайте новый реестр:
'use client'
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { StyleRegistry, createStyleRegistry } from 'styled-jsx'
export default function StyledJsxRegistry({
children,
}: {
children: React.ReactNode
}) {
// Создаём таблицу стилей только один раз с ленивым начальным состоянием
// x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
const [jsxStyleRegistry] = useState(() => createStyleRegistry())
useServerInsertedHTML(() => {
const styles = jsxStyleRegistry.styles()
jsxStyleRegistry.flush()
return <>{styles}</>
})
return <StyleRegistry registry={jsxStyleRegistry}>{children}</StyleRegistry>
}
'use client'
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { StyleRegistry, createStyleRegistry } from 'styled-jsx'
export default function StyledJsxRegistry({ children }) {
// Создаём таблицу стилей только один раз с ленивым начальным состоянием
// x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
const [jsxStyleRegistry] = useState(() => createStyleRegistry())
useServerInsertedHTML(() => {
const styles = jsxStyleRegistry.styles()
jsxStyleRegistry.flush()
return <>{styles}</>
})
return <StyleRegistry registry={jsxStyleRegistry}>{children}</StyleRegistry>
}
Затем оберните ваш корневой макет реестром:
import StyledJsxRegistry from './registry'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html>
<body>
<StyledJsxRegistry>{children}</StyledJsxRegistry>
</body>
</html>
)
}
import StyledJsxRegistry from './registry'
export default function RootLayout({ children }) {
return (
<html>
<body>
<StyledJsxRegistry>{children}</StyledJsxRegistry>
</body>
</html>
)
}
Styled Components
Ниже приведён пример настройки styled-components@6
или новее:
Сначала используйте API styled-components
для создания глобального компонента реестра, который собирает все CSS-правила, сгенерированные во время рендеринга, и функцию для возврата этих правил. Затем используйте хук useServerInsertedHTML
для вставки стилей, собранных в реестре, в тег <head>
HTML в корневом макете.
'use client'
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { ServerStyleSheet, StyleSheetManager } from 'styled-components'
export default function StyledComponentsRegistry({
children,
}: {
children: React.ReactNode
}) {
// Создаём таблицу стилей только один раз с ленивым начальным состоянием
// x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet())
useServerInsertedHTML(() => {
const styles = styledComponentsStyleSheet.getStyleElement()
styledComponentsStyleSheet.instance.clearTag()
return <>{styles}</>
})
if (typeof window !== 'undefined') return <>{children}</>
return (
<StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
{children}
</StyleSheetManager>
)
}
'use client'
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { ServerStyleSheet, StyleSheetManager } from 'styled-components'
export default function StyledComponentsRegistry({ children }) {
// Создаём таблицу стилей только один раз с ленивым начальным состоянием
// x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet())
useServerInsertedHTML(() => {
const styles = styledComponentsStyleSheet.getStyleElement()
styledComponentsStyleSheet.instance.clearTag()
return <>{styles}</>
})
if (typeof window !== 'undefined') return <>{children}</>
return (
<StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
{children}
</StyleSheetManager>
)
}
Оберните children
корневого макета компонентом реестра стилей:
import StyledComponentsRegistry from './lib/registry'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html>
<body>
<StyledComponentsRegistry>{children}</StyledComponentsRegistry>
</body>
</html>
)
}
import StyledComponentsRegistry from './lib/registry'
export default function RootLayout({ children }) {
return (
<html>
<body>
<StyledComponentsRegistry>{children}</StyledComponentsRegistry>
</body>
</html>
)
}
Полезно знать:
- Во время серверного рендеринга стили будут извлечены в глобальный реестр и добавлены в
<head>
вашего HTML. Это гарантирует, что правила стилей будут размещены перед любым контентом, который может их использовать. В будущем мы можем использовать предстоящую функцию React для определения места вставки стилей.- Во время потоковой передачи стили из каждого фрагмента будут собираться и добавляться к существующим стилям. После завершения гидратации на стороне клиента
styled-components
возьмёт на себя управление, как обычно, и будет вставлять любые дополнительные динамические стили.- Мы специально используем клиентский компонент на верхнем уровне дерева для реестра стилей, потому что это более эффективный способ извлечения CSS-правил. Это позволяет избежать повторного создания стилей при последующих серверных рендерингах и предотвращает их отправку в полезной нагрузке серверного компонента.