question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItĀ collects links to all the places you might be looking at while hunting down a tough bug.

And, if youā€™re still stuck at the end, weā€™re happy to hop on a call to see how we can help out.

[theme] How to access theme from ThemeProvider with React class and functional components

See original GitHub issue

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Current behavior šŸ˜Æ

Iā€™m looking to pass my theme into the entire tree, since Iā€™ve defined colors and overridden other defaults. The documentation does not provide an official ā€œblessedā€ way as far as I can see.

const theme = createTheme({
  palette: {
    primary: {
      main: '#0d346a',
      100: '#d4e3f9',
      200: '#90b8f1',
      500: '#2e507e',
      600: '#203857',
      700: '#152438'
    },
  }, // other overrides 
})

class App extends React.Component {
  render() {
    return (
      <ThemeProvider theme={theme}>
        <CssBaseline />
        <MyClassComponent />
      </ThemeProvider>
     )
  }
}

My questions:

  1. How do I access the ā€œthemeā€ prop in class components?
  2. How do I access the ā€œthemeā€ prop in functional components? The useTheme hook is apparently deprecated.
  3. How do I make TypeScript happy?
  4. Can the docs be updated to provide examples of the above questions? There is only the example of how to declare the ThemeProvider and use it as a root component: https://mui.com/customization/theming/#themeprovider

Expected behavior šŸ¤”

I would expect to be able to do something like the below:

export class MyClassComponent extends React.Component {
  render() {
    const { theme } = this.props // TypeScript Error: Property 'theme' does not exist on type 'Readonly<{}> & Readonly<{ children?: ReactNode; }>'.ts(2339)
    return (
      <Box 
        sx={{ backgroundColor: theme.palette.primary[600], px: theme.spacing(1) }}
      />
    )
  }
}

export const MyFunctionComponent = () => {
  const theme = useTheme() // Apparently deprecated, listed under API (Legacy). See legacy doc page: https://mui.com/styles/api/#usetheme-theme
  return (
    <Box 
      sx={{ backgroundColor: theme.palette.primary[600], px: theme.spacing(1) }}
    />
  )
}

Steps to reproduce šŸ•¹

No response

Context šŸ”¦

No response

Your environment šŸŒŽ

`npx @mui/envinfo`
  System:
    OS: macOS 12.1
  Binaries:
    Node: 14.19.1 - ~/.nvm/versions/node/v14.19.1/bin/node
    Yarn: 1.22.10 - /usr/local/opt/yarn/bin/yarn
    npm: 6.14.16 - ~/.nvm/versions/node/v14.19.1/bin/npm
  Browsers:
    Chrome: 100.0.4896.75 <-- I generally use Chrome for development 
    Edge: Not Found
    Firefox: Not Found
    Safari: 15.2
  npmPackages:
    @emotion/react: ^11.8.2 => 11.8.2 
    @emotion/styled: ^11.8.1 => 11.8.1 
    @mui/base:  5.0.0-alpha.74 
    @mui/icons-material: ^5.5.1 => 5.5.1 
    @mui/lab: ^5.0.0-alpha.76 => 5.0.0-alpha.76 
    @mui/material: ^5.5.3 => 5.5.3 
    @mui/private-theming:  5.6.0 
    @mui/styled-engine:  5.6.0 
    @mui/system:  5.6.0 
    @mui/types:  7.1.3 
    @mui/utils:  5.6.0 
    @mui/x-date-pickers:  5.0.0-alpha.0 
    @types/react: ^17.0.20 => 17.0.43 
    react: ^18.0.0 => 18.0.0 
    react-dom: ^18.0.0 => 18.0.0 
    typescript: ^4.4.2 => 4.6.3 

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:1
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

4reactions
chrisl777commented, Apr 8, 2022

@michaldudak Thank you for the reply!

For functional components, Iā€™m glad to know that useTheme is okay to use. Youā€™re right it was confusing as the docs make it seem like useTheme is deprecated. For example, the page on Theming does not mention useTheme at all: https://mui.com/customization/theming/. You have to dig into the legacy or migration guide docs to find it, at least as far as when I search for useTheme in the search at the top of the docs.

For class components, it sounds like Iā€™ll need to create a higher-order component (HOC). It would be great if the docs had an example of that HOC (for TypeScript as well).

The issue I have with TypeScript comes when using class components bringing in the theme. Before, we had the WithTheme interface to denote the theme prop for class components (otherwise TypeScript would complain), like so:

class MyThemedClassComponent extends React.Component<WithTheme> {
  render() {
    const { theme } = this.props 
    return (
      <Box 
        sx={{ backgroundColor: theme.palette.primary[600] }}
      />
    )
  }
}

export default withTheme(MyThemedClassComponent)

Of course, I can copy this pattern for my custom HOC wrapper, but it would be nice if there were a ā€œblessedā€ way in the docs to explain how to use the theme in class components with an HOC. Now that the WithTheme interface has been removed, itā€™s not obvious to me the sanctioned approach.

2reactions
michaldudakcommented, Apr 8, 2022

Hi @chrisl777. It seems the docs are incomplete. Iā€™ll make sure to correct them. As for your questions:

How do I access the ā€œthemeā€ prop in class components?

@mnajdova please correct me if Iā€™m wrong. AFAIK you have to wrap your class component in a function one and access the theme object via a hook (described below)

How do I access the ā€œthemeā€ prop in functional components? The useTheme hook is apparently deprecated.

The @mui/styles package is deprecated. However, we export useTheme from the @mui/material package. It is a supported and recommended way of accessing the theme. I realize the docs point to this deprecated package and it may be confusing.

How do I make TypeScript happy?

Could you be more specific?

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to get the theme outside styled-components?
import React, { useTheme } from 'styled-components'; export function ... Then, call it on the component you need to access the theme :...
Read more >
Theming and Theme Switching with React and styled ...
Select and apply a theme ... We can now use the theme structure and supply the theme object to the <ThemeProvider> wrapper. First,...
Read more >
Build a React theme switcher app with styled-components
We'll use ThemeProvider to enable theme switching. First, let's import ThemeProvider and then import our Themes from the Theme.
Read more >
Advanced Usage - styled-components
This component provides a theme to all React components underneath itself via the context API. In the render tree all styled-components will have...
Read more >
3 Ways To Theme React Components - Bits and Pieces
3 Ways To Theme React Components Ā· 1. CSS Variables Ā· 2. styled-components Ā· 3. Descendant Combinator.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found