1

I'm following the official tutorial to create global theme for my app.

My root component is supposed to provide global theme:

const themeInstance = {
  backgroundColor: 'cadetblue'
}

render (
    <ThemeProvider theme={themeInstance}>
      <ChildComponent />
    </ThemeProvider>,
    rootNode
) 

But I can't seem to get my child component to apply the theme:

const useStyles = makeStyles(theme => {
  childComp: {
    backgroundColor: theme.backgroundColor
  }
})

const ChildComponent: FC = () => {
  const classes = useStyles()
  return (
    <div className={classes.childComp}>I'm a div</div>
  )
}

<ChildComponent /> is getting rendered un-styled.

It looks to be a types mismatch issue of some sort as when I started to play around with types of theme parameter, the browser has rendered the expected output (<ChildComponent /> div with background-color: cadetblue) for split second than failed with error.

Any help to figure out where did I go wrong way are quite appreciated.

Live sandbox can be found over here.


2 Answers 2

1

You need to type your custom theme. By default makeStyle will use default theme type which has the following signature:

export interface Theme {
  shape: Shape;
  breakpoints: Breakpoints;
  direction: Direction;
  mixins: Mixins;
  components?: Components;
  palette: Palette;
  shadows: Shadows;
  spacing: Spacing;
  transitions: Transitions;
  typography: Typography;
  zIndex: ZIndex;
  unstable_strictMode?: boolean;
}

As you can see, it doesn't have backgroundColor property. You need to update the Theme definition by using module augmentation to make typescript stop complaining about the incorrect theme type.

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

declare module "@material-ui/styles" {
  interface DefaultTheme extends MyTheme {}
}

declare module "@material-ui/core/styles/createMuiTheme" {
  interface ThemeOptions extends MyTheme {}
}

export interface MyTheme extends Theme {
  backgroundColor: string;
}

const theme = createMuiTheme({
  backgroundColor: "red"
});

export { theme };

In your component

const useStyles = makeStyles((theme) => ({
  childComp: {
    backgroundColor: theme.backgroundColor
  }
}));

Live Demo

Edit 64294250/global-theme-with-typescript-react-material-ui

Sign up to request clarification or add additional context in comments.

Comments

1

This happens to me often. Try the following:

const useStyles = makeStyles(theme => ({
  childComp: {
    backgroundColor: theme.backgroundColor
  }
}));

Note the ( )

Live sandbox: https://stackblitz.com/edit/react-ts-e7vw8s?file=childComponent.tsx

2 Comments

@ZChu I believe the correct way is to setup a palette in your global style and access it everywhere else. I'm not sure why backgroundColor is not accessible via the default Theme type but you could just (theme: any) to get around it until you eventually setup the palette.
@ZChu Ahh, I noticed you did make a custom global theme. You should follow material-ui.com/customization/theming

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.