Material-UI + Next js - TypeError: theme.spacing не является функцией - PullRequest
1 голос
/ 26 апреля 2020

Я столкнулся с этой проблемой после того, как изменил _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),

Я не знаю, что мне не хватает. Любая помощь будет оценена.

1 Ответ

0 голосов
/ 02 мая 2020

Я решил это, позвонив createMuiThemeFromBrand в пределах MyApp(props)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...