Использование CSS-in-JS библиотек
Предупреждение: Использование CSS-in-JS с новыми функциями React, такими как Серверные Компоненты и Потоковая передача, требует от авторов библиотек поддержки последней версии React, включая конкурентный рендеринг.
Следующие библиотеки поддерживаются в Клиентских Компонентах в директории app
(в алфавитном порядке):
ant-design
chakra-ui
@fluentui/react-components
kuma-ui
@mui/material
@mui/joy
pandacss
styled-jsx
styled-components
stylex
tamagui
tss-react
vanilla-extract
Следующие библиотеки в настоящее время работают над поддержкой:
Полезно знать: Мы тестируем различные CSS-in-JS библиотеки и будем добавлять больше примеров для библиотек, поддерживающих функции React 18 и/или директорию
app
.
Настройка 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
или новее:
Сначала включите styled-components в next.config.js
.
module.exports = {
compiler: {
styledComponents: true,
},
}
Затем используйте 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-правил. Это позволяет избежать повторного генерации стилей при последующих серверных рендерах и предотвращает их отправку в полезной нагрузке Серверного Компонента.
- Для сложных случаев использования, когда вам нужно настроить отдельные свойства компиляции styled-components, вы можете прочитать нашу справочную документацию по API Next.js для styled-components, чтобы узнать больше.