我无法遵循实现 Material UI 媒体查询的文档,因为它是为普通 React 应用程序指定的,而我正在使用 NextJs。具体来说,我不知道将文档指定的以下代码放在哪里:
import ReactDOMServer from 'react-dom/server';
import parser from 'ua-parser-js';
import mediaQuery from 'css-mediaquery';
import { ThemeProvider } from '@material-ui/core/styles';
function handleRender(req, res) {
const deviceType = parser(req.headers['user-agent']).device.type || 'desktop';
const ssrMatchMedia = query => ({
matches: mediaQuery.match(query, {
// The estimated CSS width of the browser.
width: deviceType === 'mobile' ? '0px' : '1024px',
}),
});
const html = ReactDOMServer.renderToString(
<ThemeProvider
theme={{
props: {
// Change the default options of useMediaQuery
MuiUseMediaQuery: { ssrMatchMedia },
},
}}
>
<App />
</ThemeProvider>,
);
// …
}
我想要实现这一点的原因是因为我使用媒体查询来有条件地呈现某些组件,如下所示:
const xs = useMediaQuery(theme.breakpoints.down('sm'))
...
return(
{xs ?
<p>Small device</p>
:
<p>Regular size device</p>
}
)
我知道我可以使用 Material UI,Hidden
但我喜欢这种方法,其中媒体查询是具有状态的变量,因为我也使用它们来有条件地应用 css。
我已经styled components
在 SRR 中使用Material UI 的样式。这是我的_app.js
import NextApp from 'next/app'
import React from 'react'
import { ThemeProvider } from 'styled-components'
const theme = {
primary: '#4285F4'
}
export default class App extends NextApp {
componentDidMount() {
const jssStyles = document.querySelector('#jss-server-side')
if (jssStyles && jssStyles.parentNode)
jssStyles.parentNode.removeChild(jssStyles)
}
render() {
const { Component, pageProps } = this.props
return (
<ThemeProvider theme={theme}>
<Component {...pageProps} />
<style jsx global>
{`
body {
margin: 0;
}
.tui-toolbar-icons {
background: url(${require('~/public/tui-editor-icons.png')});
background-size: 218px 188px;
display: inline-block;
}
`}
</style>
</ThemeProvider>
)
}
}
这是我的 _document.js
import React from 'react'
import { Html, Head, Main, NextScript } from 'next/document'
import NextDocument from 'next/document'
import { ServerStyleSheet as StyledComponentSheets } from 'styled-components'
import { ServerStyleSheets as MaterialUiServerStyleSheets } from '@material-ui/styles'
export default class Document extends NextDocument {
static async getInitialProps(ctx) {
const styledComponentSheet = new StyledComponentSheets()
const materialUiSheets = new MaterialUiServerStyleSheets()
const originalRenderPage = ctx.renderPage
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: App => props =>
styledComponentSheet.collectStyles(
materialUiSheets.collect(<App {...props} />)
)
})
const initialProps = await NextDocument.getInitialProps(ctx)
return {
...initialProps,
styles: [
<React.Fragment key="styles">
{initialProps.styles}
{materialUiSheets.getStyleElement()}
{styledComponentSheet.getStyleElement()}
</React.Fragment>
]
}
} finally {
styledComponentSheet.seal()
}
}
render() {
return (
<Html lang="es">
<Head>
<link
href="https://fonts.googleapis.com/css?family=Comfortaa|Open+Sans&display=swap"
rel="stylesheet"
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}