Are you familiarized with React's Context API? From styled-components docs:

styled-components has full theming support by exporting a <ThemeProvider> wrapper component. This component provides a theme to all React components underneath itself via the context API.

Let's see how we could implement a ThemeProvider with styled-components.

1. First we need to create a Context to encapsulate our theming logic

We should also create a "custom hook" to ease access to our context throughout our app.

theme-context.jsx

import React from 'react'

export const ThemeContext = React.createContext({
  // our theme object
  theme: {},
  // our color modes ('dark' || 'light')
  colorMode: '',
  // a method to toggle our theme from `dark` to `light` and vice-versa
  setColorMode: () => null,
})

// export our custom hook for quick access to our context
export function useTheme() {
  return React.useContext(ThemeContext)
}
2. Now we need to extend styled-components native <ThemeProvider> to create our own ThemeProvider

Since we'll need access to our themes, I'll add two very contrived theme objects (for the sake of simplicity) as well.

theme-provider.jsx

import React from 'react'
import { ThemeProvider as StyledProvider } from 'styled-components'
import { ThemeContext } from './theme-context'

// our theme objects
const lightTheme = { colorMode: 'light', bg: '#fff', text: '#000' }
const darkTheme = { colorMode: 'dark', bg: '#000', text: '#fff' }

// our iterable theme "store"
const myThemes = [lightTheme, darkTheme]

// our default color mode
const defaultColorMode = 'light'

const ThemeProvider = ({ children, ...props }) => {
  // get fallback values from the parent ThemeProvider (if exists)
  const {
    theme: fallbackTheme,
    colorMode: fallbackColorMode,
  } = useTheme()

  // initialize our state
  const theme = props.theme ?? fallbackTheme
  const [colorMode, setColorMode] = React.useState(
    props.colorMode ?? fallbackColorMode ?? defaultColorMode,
  )

  // memoize the current theme
  const resolvedTheme = React.useMemo(() => {
    const theme = myThemes.find(t => t.colorMode === colorMode)
    if (theme) return theme
    return lightTheme
  }, [theme, myThemes, colorMode])

  // update our state if props change
  React.useEffect(() => {
    setColorMode(props.colorMode ?? fallbackColorMode ?? defaultColorMode)
  }, [props.colorMode, fallbackColorMode])

 return (
    <ThemeContext.Provider
      value={{
        theme: resolvedTheme,
        colorMode,
        setColorMode,
      }}
    >
      <StyledProvider theme={resolvedTheme}>{children}</StyledProvider>
    </ThemeContext.Provider>
  )
}

export default ThemeProvider
3. Our final step is wrapping up our main <App /> component within our ThemeProvider

app.jsx

import React from 'react'
import ThemeProvider from './theme-provider'

const App = () => {
  const [themeType, setThemeType] = React.useState('light')
  const switchThemes = () => {
    setThemeType(last => (last === 'dark' ? 'light' : 'dark'))
  }

  return (
    <ThemeProvider colorMode={themeType}>
      <MySwitch onClick={switchThemes} />
    </ThemeProvider>
  )
}

And that's it. We should now be able to toggle our theme by clicking on MySwitch. Hope that helps!

Let me know how it goes? Cheers

Answer from Moa on Stack Overflow
🌐
styled-components
styled-components.com › docs › advanced
styled-components
styled-components has full theming support by exporting a <ThemeProvider> wrapper component. This component provides a theme to all React components underneath itself via the context API.
🌐
DEV Community
dev.to › aromanarguello › how-to-use-themes-in-styled-components-49h
How to use Themes in styled-components - DEV Community
November 26, 2022 - Then, using the render props method we will create a Theme component that will render children with all the properties from the Theme provider. Like I mentioned before, the theme provider takes a theme prop. In that prop is where we reference the object we create above. const Theme = ({ children }) => ( <ThemeProvider theme={theme}>{children}</ThemeProvider> ); Finally, we export the theme. import React from "react"; import { ThemeProvider } from "styled-components"; const theme = { colors: { powderWhite: "#FFFDF9", persianGreen: "#06B49A", lightBlue: "#AFDBD2", onyx: "#36313D" }, fonts: ["sans-serif", "Roboto"], fontSizes: { small: "1em", medium: "2em", large: "3em" } }; const Theme = ({ children }) => ( <ThemeProvider theme={theme}>{children}</ThemeProvider> ); export default Theme;
Discussions

Default theme for components without parent ThemeProvider
Problem: When you are using styled-components to create a component library that supports themes, the components require a ThemeProvider in the tree. This can be undesirable if the components are m... More on github.com
🌐 github.com
9
January 13, 2020
Using Styled-Components with a theme provider. How should I organize my colors?
There’s a lot of ways to do this, I’ve often had more than the simple obiect you have there, with groups of arrays containing color steps. One thing to look into is a library called Style Dictionary made by Amazon that you can use to build design tokens to use in any number of formats. They have lots of examples on how to format your tokens for that system, and they get exported to flat, named tokens for you to use. More on reddit.com
🌐 r/reactjs
1
4
June 3, 2022
Implement different themes using styled components
This component provides a theme to all React components underneath itself via the context API. Let's see how we could implement a ThemeProvider with styled-components. More on stackoverflow.com
🌐 stackoverflow.com
reactjs - How to get the theme outside styled-components? - Stack Overflow
I just found this article which explains the problem with Context and provides a solution: medium.com/@mweststrate/… It turns out that this solution is what styled-components does internally and in my answer I'm subscribing to styled-components context. More on stackoverflow.com
🌐 stackoverflow.com
🌐
GitHub
github.com › styled-components › styled-theming
GitHub - styled-components/styled-theming: Create themes for your app using styled-components
<ThemeProvider> is part of styled-components, but is required for styled-theming. import {ThemeProvider} from 'styled-components'; <ThemeProvider> accepts a single prop theme which you should pass an object with either strings or getter functions.
Starred by 1.2K users
Forked by 25 users
Languages   JavaScript 97.6% | HTML 2.4% | JavaScript 97.6% | HTML 2.4%
🌐
GitHub
github.com › styled-components › styled-components › issues › 2960
Default theme for components without parent ThemeProvider · Issue #2960 · styled-components/styled-components
January 13, 2020 - Create a library constructor module that re-exports the whole library scoped to a custom context: const {styled, ThemeProvider} = createStyledComponents(defaultTheme) Allow anything that subscribes to context to take a custom context reference as a prop, which could be set to a custom context that does have a default value. This is what Redux does for connected components.
Author   alexkrolick
🌐
LogRocket
blog.logrocket.com › home › build a react theme switcher app with styled-components
Build a React theme switcher app with styled-components - LogRocket Blog
June 4, 2024 - ThemeProvider provides our theme to every component within its wrapper via the React Context API. We’ll use ThemeProvider to enable theme switching. First, let’s import ThemeProvider and then import our Themes from the Theme.styled.js file into the App.js file.
🌐
Emotion
emotion.sh › docs › theming
Emotion – Theming
A React hook that provides the current theme as its value. If the theme is updated, the child component will be re-rendered accordingly. import { ThemeProvider, useTheme } from '@emotion/react' ... Thanks goes to the styled-components team and their contributors who designed this API.
🌐
egghead.io
egghead.io › lessons › react-theme-your-application-with-styled-components-and-themeprovider
Theme your application with styled-components and 'ThemeProvider' | egghead.io
In this styled-components lesson, we set a "primary color" within a UI "theme" object. We make this theme accessible to all components by wrapping our application inside a <ThemeProvider>.
Published   February 1, 2020
Find elsewhere
🌐
Reddit
reddit.com › r/reactjs › using styled-components with a theme provider. how should i organize my colors?
r/reactjs on Reddit: Using Styled-Components with a theme provider. How should I organize my colors?
June 3, 2022 -

I'm making a design system for our company using Styled Components. I can create a theme and use that theme for any component that needs to reuse padding, colors, etc.

export const Theme = (props) => (
  <ThemeProvider theme={{
    fontWeights: {
      bold: 700;
      normal: 400,
      light: 100
    },
    ...
  }}>{props.children}</ThemeProvider>
);

export const Button = styled.button(props => `
  font-weight: props.theme.fontWeight.normal,
  ...
`);

The problem I'm having is colors. I don't want to specify the same HTML color codes everywhere, so I want to have them in the theme. But how do I organize them?

If I try this solution, then when I find a new situation I need to amend the color object, and it grows out of control with duplicated values and inconsistent variable names:

theme = {
  colors: {
    success: {
      font: "#2dce89",
      disabledBackground: "#abebd0",
      glow: ...
      active: ...
      borderDisabled: ...
      ...
    }
  }
}

Design sites suggest using numbers. But if I have to style a button, how do I know which color weight to use? And where do greyed versions for disabled go? What about other variants?

success: {
  100: "#d5f5e7",
  200: "#abebd0",
  300: "#81e2b8",
  400: "#57d8a1",
  500: "#2dce89",
  600: "#24a56e",
  700: "#1b7c52",
  800: "#125237",
  900: "#09291b",
},

Is there a better way to organize my colors so it is easy to be consistent across multiple components without having an explosion of one-off variables or duplicated values?

Top answer
1 of 1
2

Are you familiarized with React's Context API? From styled-components docs:

styled-components has full theming support by exporting a <ThemeProvider> wrapper component. This component provides a theme to all React components underneath itself via the context API.

Let's see how we could implement a ThemeProvider with styled-components.

1. First we need to create a Context to encapsulate our theming logic

We should also create a "custom hook" to ease access to our context throughout our app.

theme-context.jsx

import React from 'react'

export const ThemeContext = React.createContext({
  // our theme object
  theme: {},
  // our color modes ('dark' || 'light')
  colorMode: '',
  // a method to toggle our theme from `dark` to `light` and vice-versa
  setColorMode: () => null,
})

// export our custom hook for quick access to our context
export function useTheme() {
  return React.useContext(ThemeContext)
}
2. Now we need to extend styled-components native <ThemeProvider> to create our own ThemeProvider

Since we'll need access to our themes, I'll add two very contrived theme objects (for the sake of simplicity) as well.

theme-provider.jsx

import React from 'react'
import { ThemeProvider as StyledProvider } from 'styled-components'
import { ThemeContext } from './theme-context'

// our theme objects
const lightTheme = { colorMode: 'light', bg: '#fff', text: '#000' }
const darkTheme = { colorMode: 'dark', bg: '#000', text: '#fff' }

// our iterable theme "store"
const myThemes = [lightTheme, darkTheme]

// our default color mode
const defaultColorMode = 'light'

const ThemeProvider = ({ children, ...props }) => {
  // get fallback values from the parent ThemeProvider (if exists)
  const {
    theme: fallbackTheme,
    colorMode: fallbackColorMode,
  } = useTheme()

  // initialize our state
  const theme = props.theme ?? fallbackTheme
  const [colorMode, setColorMode] = React.useState(
    props.colorMode ?? fallbackColorMode ?? defaultColorMode,
  )

  // memoize the current theme
  const resolvedTheme = React.useMemo(() => {
    const theme = myThemes.find(t => t.colorMode === colorMode)
    if (theme) return theme
    return lightTheme
  }, [theme, myThemes, colorMode])

  // update our state if props change
  React.useEffect(() => {
    setColorMode(props.colorMode ?? fallbackColorMode ?? defaultColorMode)
  }, [props.colorMode, fallbackColorMode])

 return (
    <ThemeContext.Provider
      value={{
        theme: resolvedTheme,
        colorMode,
        setColorMode,
      }}
    >
      <StyledProvider theme={resolvedTheme}>{children}</StyledProvider>
    </ThemeContext.Provider>
  )
}

export default ThemeProvider
3. Our final step is wrapping up our main <App /> component within our ThemeProvider

app.jsx

import React from 'react'
import ThemeProvider from './theme-provider'

const App = () => {
  const [themeType, setThemeType] = React.useState('light')
  const switchThemes = () => {
    setThemeType(last => (last === 'dark' ? 'light' : 'dark'))
  }

  return (
    <ThemeProvider colorMode={themeType}>
      <MySwitch onClick={switchThemes} />
    </ThemeProvider>
  )
}

And that's it. We should now be able to toggle our theme by clicking on MySwitch. Hope that helps!

Let me know how it goes? Cheers

Top answer
1 of 4
40

You can use the useTheme hook since v5.0:

import React, { useTheme } from 'styled-components';

export function MyComponent() {
  const theme = useTheme();

  return <p style={{ color: theme.color }}>Text</p>;
}

You can also use the withTheme higher order component that I contributed a long time ago since v1.2:

import { withTheme } from 'styled-components'

class MyComponent extends React.Component {
  render() {
    const { theme } = this.props

    console.log('Current theme: ', theme);
    // ...
  }
}

export default withTheme(MyComponent)



original response below (ignore this!)

While there is no official solution, I came up by now:

Create a Higher Order Component that will be responsable to get the current theme and pass as a prop to a component:

import React from 'react';
import { CHANNEL } from 'styled-components/lib/models/ThemeProvider';

export default Component => class extends React.Component {
  static contextTypes = {
    [CHANNEL]: React.PropTypes.func,
  };

  state = {
    theme: undefined,
  };

  componentWillMount() {
    const subscribe = this.context[CHANNEL];
    this.unsubscribe = subscribe(theme => {
      this.setState({ theme })
    });
  }

  componentWillUnmount() {
    if (typeof this.unsubscribe === 'function') this.unsubscribe();
  }

  render() {
    const { theme } = this.state;

    return <Component theme={theme} {...this.props} />
  }
}

Then, call it on the component you need to access the theme:

import Themable from './Themable.js'
  
const Component = ({ theme }) => <Card color={theme.color} />

export default Themable(Component);
2 of 4
17

You can use useTheme hook

import { useTheme } from 'styled-components';

const ExampleComponent = () => {
  const theme = useTheme();

  return (
    <View>
       <Card aCustomColorProperty={theme.color.sampleColor} />
    </View>
  );
};
🌐
Theme-ui
theme-ui.com › guides › styled-components
Styled Components – Theme UI
Theme UI itself doesn’t expose an API for styled components, but works seamlessly with the styled API from the @emotion/styled package. Components written with it should have access to the same theming context that Theme UI uses. Instead of using the ThemeProvider component from @emotion/react, import and use the Theme UI provider at your app’s root level.
🌐
Northflank
northflank.com › blog › adding-themes-to-a-react-app-using-styled-components
How (and Why) to Add Themes to your React App Using Styled-Components | Blog — Northflank
January 25, 2022 - Then, at the root of our application, we can make styled-components aware of this theme using a ThemeProvider.
🌐
DEV Community
dev.to › boywithsilverwings › theming-with-styled-components-3ig2
Theming with Styled Components - DEV Community
March 4, 2020 - Styled Components family has a library called styled theming. It has an easier API for creating and maintaining variant based styles. For eg. To create a button that would be different in light and dark mode: import styled, {ThemeProvider} from ...
🌐
egghead.io
egghead.io › lessons › react-create-and-use-a-theme-in-styled-components
Create and use a Theme in Styled Components | egghead.io
In the index.js file, where you have your App component being rendered, we will wrap it with the ThemeProvider. We can set some colors to an object and call it theme.
🌐
Pieces
pieces.app › home
Styling Components with React Themes
Pieces for Developers – Long-Term Memory Agent
The theme object exported as the default in the code block above has two properties: dark and light. We’ll pass the proper property to the ThemeProvider component based on the selected theme. The following action will wrap the application with ThemeProvider: <pre>import styled, { ThemeProvider ... Pieces is your AI long-term memory agent that captures live context from browsers to IDEs and tools, manages snippets, and supports multiple LLMs. This app has dramatically improved my workflow!</pre>
Rating: 5 ​
🌐
Zendesk
garden.zendesk.com › components › theme-provider
Theme provider / Components / Zendesk Garden
ThemeProvider · Used for this · As the root component of the Garden DOM, where it provides global context for color mode and RTL layout · As a nested wrapper for a subset of components that require themed styling · The typical usage of a ...
🌐
CSS-Tricks
css-tricks.com › theming-and-theme-switching-with-react-and-styled-components
Theming and Theme Switching with React and styled-components | CSS-Tricks
June 15, 2022 - styled-components: A flexible way to style React components with CSS. It provides out-of-the-box theming support using a wrapper component called, <ThemeProvider>. This component is responsible for providing the theme to all other React components ...
🌐
OpenReplay
blog.openreplay.com › theming-react-native-applications-with-styled-components
Theming React Native Applications with Styled Components
March 2, 2022 - We’ve replaced the colours with props that will be passed down depending on the theme selected, so if a user selects dark mode, we’ll apply the colours from the darkMode theme in the theme.js folder to the styled-components. Now go to the App.js file and paste the code below. /** Previous code **/ import { ThemeProvider } from 'styled-components/native'; import { darkTheme, lightTheme } from './theme'; export default function App() { const [theme, setTheme] = useState('light'); const toggleTheme = async () => { const themeValue = theme === 'dark' ?
🌐
DhiWise
dhiwise.com › post › react-themeprovider-the-secret-to-effective-theming
React ThemeProvider: The Secret to Effective Theming
October 31, 2023 - We then wrap our root component (App) with the ThemeProvider and pass our theme object to it as a prop. Now, any styled component that we create inside this provider will have access to the theme object through its props.