Material-UI Theme Overrides Leveraging Theme Palette Colors

Ill provide two solutions- one is more readable and maintainable, and one has better performance.

  1. The readable and maintainable approach:
    Create nested themes.
    One theme will be for defining the palette, and one theme will be for overrides.
    Because its two themes, you can access the palette theme from overrides theme:

    const globalTheme = createMuiTheme({
      palette: {
        primary: {
          main: 'rgba(217,255,102,1)'
        }
      },
    });
    
    const overridesTheme = createMuiTheme({
      overrides: {
        MuiButton: {
            root: {
                backgroundColor: globalTheme.palette.primary.main,
            },
            label: {
              color:globalTheme.palette.primary.contrastText,
            }
        },
    }
    })
    

    You can refer to this CodeSandbox

    This approach doesn't have good performance, bacause every render a new CSS object will be computed and injected


  1. The better performance approach:
    First you create an Mui theme skeleton, with the palette. After it has been created, you add the styles that rely on the palette (notice how I have to use the spread operator a lot to avoid deleting styles):

    const theme = createMuiTheme({
      palette: {
        primary: {
          main: 'rgba(217,255,102,1)'
        }
      },
    })
    
    theme.overrides = {
      ...theme.overrides,
      MuiButton: {
          ...theme.MuiButton,
          root: {
             ...theme.root,
              backgroundColor: theme.palette.primary.main,
          },
          label: {
            ...theme.label,
            color:theme.palette.primary.contrastText,
          }
      },
    }
    

    You can refer to this CodeSandbox


There's another approach here. createMuiTheme accepts any number of additional theme objects to be merged together.

With that in mind you could replicate your accepted answer without having two different ThemeProvider. And if you move the theme definition to its own module, it won't be recreated on each render.

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

const globalTheme = createMuiTheme({
  palette: {
    primary: {
      main: "rgba(217,255,102,1)"
    }
  }
});

const theme = createMuiTheme(
  {
    overrides: {
      MuiButton: {
        root: {
          backgroundColor: globalTheme.palette.primary.main
        },
        label: {
          color: globalTheme.palette.primary.contrastText
        }
      }
    }
  },
  globalTheme
);

export default theme;

I updated the CodeSandBox to reflect this.