I need to create a context to apply dark or light theme in repositories. There will be no change of themes by button or something like that, I'll just set the theme and that's it
for now, I have context like this
import { createContext } from "react";
import { light } from './themes';
export const ThemeContext = createContext(light);
export default ThemeContext;
and my app
import { light, dark } from './themes';
<ThemeContext.Provider value={light}> // or dark, depending on the project
   <App />   
 </ThemeContext.Provider> 
);
that way is not working, how can I apply the theme?
You've created a provider which makes its value available to every child in the tree. But, any child that wants to use that value needs to consume it.
The patterns for how to consume the context are different for class components VS. function components but the basic principle is the same: you need tell your child component how to get the theme value from the context.
For function components, the simplest way is with the useContext hook (example copied straight from the hooks docs):
function ThemedButton() {
  const theme = useContext(ThemeContext);
  
  return (
    <button style={{ background: theme.background, color: theme.foreground }}>
      I am styled by theme context!
    </button>
  );
}
The above works, but there's a really nice pattern where you can wrap the consumer in a custom hook which you'd call something like useTheme (I first saw this pattern here).
// Step 1
const ThemeContext = React.createContext(undefined)
// Step 2
function ThemeProvider({children}) {
  return (
    <ThemeContext.Provider value={light}>
      {children}
    </ThemeContext.Provider>
  )
}
// Step 3
function useTheme() {
  const context = React.useContext(ThemeContext)
  
  if (context === undefined) {
    throw new Error('useTheme must be used within a ThemeProvider')
  }
  return context
}
export {ThemeProvider, useTheme}
Step 1 - Creates the context. You've already done this in your example.
Step 2 - Creates the provider. You've used a provider in "my app".
Step 3 - This is what's new. It creates a custom hook that checks that the provider is accessible (throwing an error if not) and then returns the value from the provider.
You then use the hook like this:
function ThemedButton() {
  const theme = useTheme()
  
  return <Text color={theme.textColor}>Some text</Text>
}
There are a few benefits to this pattern:
useTheme, in the components that consume the theme. If you use useContext directly, you need to import the context and the useContext hook.throw new Error('...') line will warn you if you accidentally try to use useTheme somewhere in the component tree that doesn't have access to the provider.The examples with class components are a little long and more nuanced, so I'll recommend using the docs for the details of how to do that. But, one approach is like this:
<ThemeContext.Consumer>
  {value => <ThemedButton theme={value} />
</ThemeContext.Consumer>
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With