Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is it possible to 'nest' themes in React?

I have a React app which uses the Material UI Theme Provider to set the font throughout, like this:

App.js

const App = () => {
  return (
    <BrowserRouter>
      <Routes>
        ... routes rendering various elements ...
      </Routes>
    </BrowserRouter>
  );
};

const ThemedApp = () => {
  const theme = createTheme({
    palette: {
      primary: {
        main: Colours.primaryColor,
      },
      secondary: {
        main: Colours.secondaryColor,
      },
    },
    typography: {
      fontFamily: 'serif',
      fontSize: 16,
    },
  });
  return (
    <ThemeProvider theme={theme}>
      <App />
    </ThemeProvider>
  );
};

const FirebaseApp = () => {
  return <ThemedApp />;
};

export default FirebaseApp;

(I didn’t write this code, so I’m not sure why it exports ThemedApp as FirebaseApp instead of just renaming ThemedApp to FirebaseApp or something, but that’s a different issue).

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

However, one section of the app (we’ll call it ‘DifferentFontArea’) needs to use a different font, but the rest of the theme is the same. I’ve tried ‘nesting’ the ThemeProvider like this (this component is a child of the App component shown above, and therefor wrapped within ThemeProvider):

const DifferentFontBase = () => {

    return (
      <>
        ... component details go here
      </>
    );
  }

};

const DifferentFontArea = () => {
  const theme = useTheme();
  const fontTheme = createTheme({
    ...theme,
    typography: {
      fontFamily: 'sans-serif',
    },
  });
  return (
    <ThemeProvider theme={fontTheme}>
      <DifferentFontBase />
    </ThemeProvider>
  );
};

export default DifferentFontArea;

This seems to work; when DifferentArea is rendered, it has a sans-serif font, whereas the rest of the app has the serif font. I’m just not sure whether it’s ok to nest providers like this, as I can’t find references to it in the documentation.

>Solution :

Components will use the closest provider for any context they are referencing. This means the theme created in ThemedApp is not visible, in any sense of the word, to the components inside <DifferentFontBase />, as all the components inside will be referencing the value from closer provider, i.e. fontTheme.

Whether it’s okay or not depends on your use case. It seems that, in the scenario you posted, since fontTheme references the original theme, you should be okay.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading