【问题标题】:How to use Theme in material UI with React + Next.js?如何通过 React + Next.js 在 Material UI 中使用 Theme?
【发布时间】:2020-07-16 08:37:03
【问题描述】:

我创建了如下所示的三个文件。

Paper 的颜色根据theme.js 中定义的palette.type 的值而变化。

带有调色板的页面.type: 'dark'

带有调色板的页面.type: 'light'

但是,我不明白变量 theme 的工作原理。我在index.js 中添加了两个console.log(theme)。无论theme.js 中的值如何,两者都显示palette.type: 'light'

console.log 的结果

如何将theme 传递给index.js(不导入主题)?

components/Layout.js - 将相同布局应用到所有页面的共享组件

import React from 'react';
import { MuiThemeProvider } from '@material-ui/core/styles';
import { theme } from '../utils/theme';


class Layout extends React.Component {
    render() {
        return(
            <MuiThemeProvider theme={theme}>
                {this.props.children}
            </MuiThemeProvider>
        )
    }
}

export default Layout;

pages/index.js - 一个特定页面

import Layout from '../components/Layout';
import { makeStyles, createStyles, useTheme, Paper } from '@material-ui/core';

const useStyles = makeStyles(theme => {
    console.log('inside makeStyles');
    console.log(theme);
    return createStyles({
        container: {
            margin: '5px 5px 50px 5px'
        }
    })
});

export default function Index(props) {
    const classes = useStyles(props);
    const theme = useTheme();
    console.log('inside Index')
    console.log(theme);

    return(
        <Layout>
            <h2>About</h2>
            <Paper className={classes.container}>
                <p>Sample test</p>
            </Paper>
            <Paper className={classes.container}>
                <p>Sample test2</p>
            </Paper>
        </Layout>
    )
};

utils/theme.js - 单独的文件写入theme

import { createMuiTheme } from '@material-ui/core/styles';

export const theme = createMuiTheme({
    palette: {
        type: 'dark'
    }
});

【问题讨论】:

  • 我能够复制并修复该问题。
  • 在您的屏幕截图中,主题仅应用于Paper,但如果使用正确,它也应该改变页面的背景颜色。

标签: reactjs material-design material-ui next.js


【解决方案1】:

尝试将 &lt;MuiThemeProvider theme={theme}&gt;Layout.js 移动到 _app.js

_app.js

import React from 'react';
import PropTypes from 'prop-types';
import Head from 'next/head';
import { ThemeProvider } from '@material-ui/core/styles';
import CssBaseline from '@material-ui/core/CssBaseline';
import theme from '../src/theme';

export default function MyApp(props) {
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 (
    <React.Fragment>
    <Head>
        <title>My page</title>
        <meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width" />
    </Head>
    <ThemeProvider theme={theme}>
        {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
        <CssBaseline />
        <Component {...pageProps} />
    </ThemeProvider>
    </React.Fragment>
);
}

MyApp.propTypes = {
    Component: PropTypes.func.isRequired,
    pageProps: PropTypes.object.isRequired,
};

主题应该适用于所有组件,您应该在console.log() 打印中看到dark

Official Material-UI + Next.js example

如果所有页面共享相同的布局,您可以完全删除Layout 组件。

【讨论】:

  • 添加pages/_app.js 确实有效!我还有一个问题。您对如何使用components/Layout.jspages/_app.js 有什么建议吗?他们现在以类似的方式工作。 (官网:nextjs.org/docs/advanced-features/custom-app
  • @dmjy,我已将其添加到答案的末尾。除非应用中有多个布局,否则同时拥有 Layout_app.js 并不会带来任何好处。
猜你喜欢
  • 2019-10-13
  • 2018-10-06
  • 2020-05-04
  • 2020-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-08
  • 2018-11-22
相关资源
最近更新 更多