在next.js中使用styled-component以及全局主题切换

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在next.js中使用styled-component以及全局主题切换相关的知识,希望对你有一定的参考价值。


文章目录

  • ​​使styled-component 像SPA中使用​​
  • ​​step1 安装插件​​
  • ​​step2 根目录下创建 `.babelrc`​​
  • ​​step3 创建`page/_document.js`自定义 Document​​
  • ​​参考 特别感谢​​
  • ​​[应用主题] 需完成上一步​​

使styled-component 像SPA中使用

step1 安装插件
yarn add babel-plugin-styled-components
step2 根目录下创建 ​​.babelrc​

"presets": [
"next/babel"
], // 覆盖nextjs的默认babel配置,以本文件的babel配置为准
"plugins": [
[
"styled-components",

"ssr": true
// 预编译样式
]
]
step3 创建​​page/_document.js​​自定义 Document
import Document,  html, Head, Main, NextScript  from next/document
import ServerStyleSheet from styled-components

class MyDocument extends Document
static async getInitialProps(ctx)
const sheet = new ServerStyleSheet()
// 1.这里采用react里High Order Component的方式,可以重新包装APP和所有渲染的组件
const originalRenderPage = ctx.renderPage
try
ctx.renderPage = () =>
originalRenderPage(
enhanceApp: App => (props) =>
// App挂载样式
sheet.collectStyles(<App ...props />)
)
// 因为覆盖了Document,所以要重新返回页面的props
const props = await Document.getInitialProps(ctx)
return
...props,
styles: <>props.stylessheet.getStyleElement()</>

finally
sheet.seal()



render()
return (
<Html>
<Head>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)



export default MyDocument
参考 特别感谢

​_document.js的文档​​​​styled-components 服务端渲染​

nextJS styled-components 集成

[应用主题] 需完成上一步

​_app.js​​ 只加入一个 ThemeProvide 具体在 ThemeProvide 中

import type  AppProps  from "next/app";
import ThemeProvide from "../context/ThemeProvide";

function MyApp( Component, pageProps : AppProps)
return (
<ThemeProvide>
<Component ...pageProps />
</ThemeProvide>
);

export default MyApp;

​ThemeProvide​

import 
createContext,
useState,
useCallback,
ReactNode,
useContext,
from "react";
import ThemeProvider from "styled-components";
import useMount from "../hooks";

export const lightTheme =
primary: "#51f",
fg: "#fff",
bg: "#000",
mode: "light",
;

const darkTheme =
primary: "#083f2c",
fg: "#000",
bg: "#eee",
mode: "dark",
;

const ThemeContext = createContext<undefined | (() => void)>(undefined);

export const useToggleTheme = () => useContext(ThemeContext);

const ThemeProvide = ( children : children: ReactNode ): JSX.Element =>
const [theme, setTheme] = useState(lightTheme);

const toggleMode = useCallback(() =>
setTheme(( mode ) =>
const newMode = mode == "dark" ? lightTheme : darkTheme;
localStorage.setItem("MODE", newMode.mode);
console.log("new theme mode:" + newMode.mode);
return newMode;
);
, []);

useMount(() =>
const oldMode = localStorage.getItem("MODE");
if (oldMode && oldMode != theme.mode)
toggleMode();

);

return (
<ThemeContext.Provider value=toggleMode>
<ThemeProvider theme=theme>children</ThemeProvider>
</ThemeContext.Provider>
);
;

export default ThemeProvide;

​useMount​

import  useEffect  from "react";

const useMount = (callback: any) =>
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(callback, []);
;

export default useMount;

在next.js中使用styled-component以及全局主题切换_ide


以上是关于在next.js中使用styled-component以及全局主题切换的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Nextjs + styled-components 与 material-ui 集成

CSS background-image 的 Next.js 图像优化

带有 Next.js 和样式化组件的本地字体

如何在服务器端渲染中将样式应用于 Next.js 中的 HTML?

如何在 Next.js 的活动页面上设置链接组件的样式

Next.js 为导入的图像返回(失败)net::ERR_UNKNOWN_URL_SCHEME