#reactjs #material-ui #next.js #emotion
#reactjs #материал-пользовательский интерфейс #next.js #эмоции
Вопрос:
Я пытаюсь создать следующее приложение, которое использует многомерные выражения для создания страниц и материалов -UI v5 Emotion, и я хочу, чтобы оно работало даже с отключенным JavaScript через статическую генерацию сайта. Я последовал этому примеру из репозитория Material UI, чтобы продолжить, но я застрял. Стили не применяются одинаково хорошо, когда JS отключен.
Вот как это выглядит с включенным JS:
И вот как это выглядит с отключенным JS:
Соответствующие файлы:
_document.tsx
import React from "react";
import Document, {
Html,
Head,
Main,
NextScript,
DocumentContext,
} from "next/document";
import { ServerStyleSheets } from "@material-ui/core/styles";
import createEmotionServer from "@emotion/server/create-instance";
import theme from "../styles/theme";
import { cache } from "./_app";
const { extractCritical } = createEmotionServer(cache);
class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
// Render app and page and get the context of the page with collected side effects.
const sheets = new ServerStyleSheets();
const originalRenderPage = ctx.renderPage;
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) => sheets.collect(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
const styles = extractCritical(initialProps.html);
return {
...initialProps,
// Styles fragment is rendered after the app and page rendering finish.
styles: [
...React.Children.toArray(initialProps.styles),
sheets.getStyleElement(),
<style
key="emotion-style-tag"
data-emotion={`css ${styles.ids.join(" ")}`}
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: styles.css }}
/>,
],
};
}
render() {
return (
<Html lang="en">
<Head>
<meta
name="description"
content="A template for creating amazing docs for your projects"
/>
<meta name="theme-color" content={theme.palette.primary.main} />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700amp;display=swap"
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
_app.tsx:
import React from "react";
import { ThemeProvider } from "@material-ui/core/styles";
import CssBaseline from "@material-ui/core/CssBaseline";
import { Container } from "@material-ui/core";
import type { AppProps } from "next/app";
import { MDXProvider } from "@mdx-js/react";
import CodeBlock from "../components/CodeBlock";
import AppBar from "../components/AppBar";
import theme from "../styles/theme";
import Head from "next/head";
import { CacheProvider } from "@emotion/react";
import createCache from "@emotion/cache";
export const cache = createCache({ key: "css", prepend: true });
export default function App(props: AppProps) {
const { Component, pageProps } = props;
React.useEffect(() => {
// Remove the server-side injected CSS.
const jssStyles = document.querySelector("#jss-server-side");
if (jssStyles) {
jssStyles.parentElement!.removeChild(jssStyles);
}
}, []);
return (
<CacheProvider value={cache}>
<Head>
<title>Next.js Doc creator</title>
<meta name="viewport" content="initial-scale=1, width=device-width" />
</Head>
<ThemeProvider theme={theme}>
<CssBaseline />
<MDXProvider
components={{
code: CodeBlock,
}}
>
<AppBar />
<Container>
<Component {...pageProps} />
</Container>
</MDXProvider>
</ThemeProvider>
</CacheProvider>
);
}
компоненты/AppBar.tsx:
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles';
import { AppBar, Button, IconButton, Toolbar, Typography } from "@material-ui/core";
import MenuIcon from "@material-ui/icons/Menu";
const useStyles = makeStyles((theme: Theme) => createStyles({
root: {
flexGrow: 1,
},
menuButton: {
marginRight: theme.spacing(2),
},
title: {
flexGrow: 1,
},
}));
function MainAppBar() {
const classes = useStyles()
return (
<AppBar position="static">
<Toolbar>
<IconButton
edge="start"
className={classes.menuButton}
color="inherit"
aria-label="menu"
>
<MenuIcon />
</IconButton>
<Typography variant="h6" className={classes.title} component="div">
Your Awesome App
</Typography>
</Toolbar>
</AppBar>
);
}
export default MainAppBar;
PS: Я использую next build amp;amp; next export
в своем package.json для SSG.
Комментарии:
1. Может ли это быть связано
App
сuseEffect
тем, что хук не запускается, когда JS отключен?2. Можете ли вы попробовать стилизовать свой компонент без использования makeStyles?