Next.jsでmaterial-uiのmakestyleを効かせる
Next.js で SSR が有効な場合 material ui の css が機能しない、チラツキがある
SSR では以下の手順を行う必要がある
リクエストがあるとnew ServerStyleSheetsを実行
サーバで css と共に React tree を生成
css を抜く
クライアントに css を適用
今回の場合はmakeStyleがうまく適応されなかった
_app.js
code:js
export default function MyApp({ Component, pageProps }) {
// 上記の「css を抜く」に該当する
// SSR で生成された css を削除する
React.useEffect(() => {
const jssStyles = document.querySelector("#jss-server-side");
if (jssStyles) {
jssStyles.parentElement.removeChild(jssStyles);
}
}, []);
return (
<Component {...pageProps} />
);
}
_document.js
下の説明と照らし合わせると良い
code:js
export default class MyDocument extends Document {
...
}
MyDocument.getInitialProps = async (context) => {
const sheet = new ServerStyleSheets();
const originalRenderPage = context.renderPage;
context.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) => sheet.collect(<App {...props} />),
// App コンポーネントを style を伝える Provider Component で包む
});
const initialProps = await Document.getInitialProps(context);
return {
...initialProps,
styles: [
...React.Children.toArray(initialProps.styles),
sheet.getStyleElement(),
],
};
};
ServerStyleSheets()
sheet.collect
The method wraps your React node in a provider element. It collects the style sheets during the rendering so they can be later sent to the client.
renderPage
ここらへんのコードはなにかを応用したというわけではなく、もはや css-in-js のためにつくられたコードなので、1行づつ理解する必要ななさそう
It should be noted that the only reason you should be customizing renderPage is for usage with css-in-js libraries that need to wrap the application to properly work with server-side rendering.