Я столкнулся с этой проблемой после того, как изменил _app.js
для динамического создания темы пользовательского интерфейса материала. Я следовал примеру реализации команды material-ui: https://github.com/mui-org/material-ui/tree/master/examples/nextjs.
Короче говоря,
- Я получаю цвета темы из REST - создание темы с использованием
createMuiTheme
- Передача созданной темы в
_app.js
prop
У меня есть контроллер, который извлекает информацию, относящуюся к теме
\\ Brand.ts
export async function getBrand(): Promise<Brand> {
const api = `${api_url}/brand`;
try {
const response = await fetch(api);
const { data } = await response.json();
console.log(data);
if (data.length > 0) {
const brand: Brand = {
primary_main: data[0].primary_main,
primary_contrastText: data[0].primary_contrastText,
secondary_main: data[0].secondary_main,
secondary_contrastText: data[0].secondary_contrastText,
error_main: data[0].error_main,
background_default: data[0].background_default
}
return brand;
} else {
return getDefaulBrand();
}
} catch (error) {
console.log('error');
return getDefaulBrand();
}
}
function createMuiThemeFromBrand(brand: Brand) {
return createMuiTheme({
palette: {
primary: {
main: brand.primary_main,
contrastText: brand.primary_contrastText,
},
secondary: {
main: brand.secondary_main,
contrastText: brand.secondary_contrastText,
},
error: {
main: brand.error_main,
},
background: {
default: brand.background_default,
},
},
});
}
export default async function getBrandTheme() {
const brand = await getBrand();
return createMuiThemeFromBrand(brand);
}
Моя тема . js файл выглядит следующим образом:
// theme.js
import getBrand from "./controller/Brand";
export default getBrand;
измененный _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 getBrand from "../src/theme"; // <- get brand
import App from "next/app";
MyApp.getInitialProps = async (appContext) => {
// calls page's `getInitialProps` and fills `appProps.pageProps`
const appProps = await App.getInitialProps(appContext);
// get theme from server
// -----------------------------
const theme = await getBrand();
// -----------------------------
return { ...appProps, theme };
};
export default function MyApp(props) {
const { Component, pageProps, theme } = 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.elementType.isRequired,
pageProps: PropTypes.object.isRequired,
};
Теперь проблема в том, что большинство работает нормально (цвет фона и и др c). НО я не могу использовать какие-либо функции, такие как (перечисленные ниже) на любой из страниц на стороне клиента.
- theme.spacing
- theme.breakpoint
Пример страницы:
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
menuButton: {
marginRight: theme.spacing(10),
},
}));
export default function Index() {
const classes = useStyles();
return (
<div className={classes.root}> ....
)
}
При рендеринге - я получаю:
TypeError: theme.spacing is not a function for
from:
marginRight: theme.spacing(10),
Я не знаю, что мне не хватает. Любая помощь будет оценена.