cbd*_*per 4 typescript next.js
我从关于如何使用的官方文档示例中获得了大部分代码styled-components
:
https://github.com/vercel/next.js/blob/canary/examples/with-styled-components/pages/_document.js
但是这个例子使用了.js
,我正在使用 Typescript。
我收到了一些类型错误和警告,我不确定如何正确输入。我已经解决了部分问题。这是我仍然缺少的:
错误 1:static async getInitialProps(ctx)
函数的完整签名类型或返回类型应该是什么?ctx
参数的类型是什么?
错误 2:对 的不安全访问ctx.renderPage
。我想这将在我正确键入getInitialProps
函数后修复
错误 3:这也可能与缺少的类型有关getInitialProps
import React, { ReactElement } from "react";
import Document, { Html, Head, Main, NextScript } from 'next/document';
import { ServerStyleSheet } from "styled-components";
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
sheet.collectStyles(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
};
} finally {
sheet.seal();
}
}
render(): ReactElement {
return(
<Html lang="en">
<Head>
// SOMETHING IN THE HEAD
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
Run Code Online (Sandbox Code Playgroud)
ras*_*tay 22
分享我的使 _ document.tsx typescript 兼容的版本,特别是当您带着情感使用 Material UI 时。
_文档.tsx
import * as React from 'react'
import Document, {
Html,
Head,
Main,
NextScript,
DocumentContext,
DocumentInitialProps,
} from 'next/document'
import createEmotionServer from '@emotion/server/create-instance'
import { theme, createEmotionCache } from '@theme'
import { AppType } from 'next/dist/shared/lib/utils'
import { EmotionCache } from '@emotion/cache'
interface DocumentProps extends DocumentInitialProps {
emotionStyleTags: React.ReactNode[]
}
const MyDocument = (props: DocumentProps) => {
return (
<Html lang="en">
<Head>
{/* PWA primary color */}
<meta name="theme-color" content={theme.palette.primary.main} />
<link rel="shortcut icon" href="/static/favicon.ico" />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
/>
{/* Inject MUI styles first to match with the prepend: true configuration. */}
{props.emotionStyleTags}
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
// `getInitialProps` belongs to `_document` (instead of `_app`),
// it's compatible with static-site generation (SSG).
MyDocument.getInitialProps = async (
ctx: DocumentContext
): Promise<DocumentProps> => {
// Resolution order
//
// On the server:
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. document.getInitialProps
// 4. app.render
// 5. page.render
// 6. document.render
//
// On the server with error:
// 1. document.getInitialProps
// 2. app.render
// 3. page.render
// 4. document.render
//
// On the client
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. app.render
// 4. page.render
const originalRenderPage = ctx.renderPage
// You can consider sharing the same emotion cache between all the SSR requests to speed up performance.
// However, be aware that it can have global side effects.
const cache = createEmotionCache()
const { extractCriticalToChunks } = createEmotionServer(cache)
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (
App: AppType | React.ComponentType<{ emotionCache: EmotionCache }>
) =>
function EnhanceApp(props) {
return <App emotionCache={cache} {...props} />
},
})
const initialProps = await Document.getInitialProps(ctx)
// This is important. It prevents emotion to render invalid HTML.
// See https://github.com/mui/material-ui/issues/26561#issuecomment-855286153
const emotionStyles = extractCriticalToChunks(initialProps.html)
const emotionStyleTags = emotionStyles.styles.map((style) => (
<style
data-emotion={`${style.key} ${style.ids.join(' ')}`}
key={style.key}
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: style.css }}
/>
))
return {
...initialProps,
emotionStyleTags,
}
}
export default MyDocument
Run Code Online (Sandbox Code Playgroud)
主题.ts
import { createTheme } from '@mui/material/styles'
import { red } from '@mui/material/colors'
// Create a theme instance.
const theme = createTheme({
palette: {
primary: {
main: '#556cd6',
},
secondary: {
main: '#19857b',
},
error: {
main: red.A400,
},
},
})
export default theme
Run Code Online (Sandbox Code Playgroud)
创建EmotionCache.ts
import createCache from '@emotion/cache'
// prepend: true moves MUI styles to the top of the <head> so they're loaded first.
// It allows developers to easily override MUI styles with other styling solutions, like CSS modules.
export default function createEmotionCache() {
return createCache({ key: 'css', prepend: true })
}
Run Code Online (Sandbox Code Playgroud)
这就是我最终为键入getInitialProps
和render
方法所做的工作:
import React, { ReactElement } from "react";
import Document, { DocumentInitialProps, DocumentContext } from 'next/document';
export default class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext): Promise<DocumentInitialProps> {
// ...
}
render(): ReactElement {
return(
// ...
);
}
}
Run Code Online (Sandbox Code Playgroud)
https://github.com/vercel/next.js/blob/canary/examples/with-styled-components/pages/_document.js
完整styled-components
示例:
import React, { ReactElement } from "react";
import Document, { Html, Head, Main, NextScript, DocumentInitialProps, DocumentContext } from 'next/document';
import { ServerStyleSheet } from "styled-components";
// NEXT.JS CUSTOM DOCUMENT
// https://nextjs.org/docs/advanced-features/custom-document
export default class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext): Promise<DocumentInitialProps> {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
sheet.collectStyles(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
};
} finally {
sheet.seal();
}
}
render(): ReactElement {
return(
<Html lang="en">
<Head>
// SOME HEAD ELEMENTS
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1390 次 |
最近记录: |