emotion-theme-provider-usetheme
position: 2
Emotion's ThemeProvider and useTheme
ThemeProvider
and useTheme
are utilities provided by Emotion that enable you to define and apply a consistent theme throughout your React application. This can include colors, fonts, spacing, and other design tokens.
ThemeProvider
ThemeProvider
is a component that allows you to define a theme and make it available to all components within your application. It works similarly to React Context by providing the theme object to the component tree.
useTheme
useTheme
is a hook that lets you access the theme object inside your functional components.
Example Usage
Step-by-Step Implementation
1. Install Emotion Packages
npm install @emotion/react @emotion/styled
2. Define a Theme Create a theme object with your design tokens.
// theme.js
export const theme = {
colors: {
primary: 'hotpink',
secondary: 'green',
},
spacing: {
small: '8px',
medium: '16px',
large: '32px',
},
};
3. Wrap Your Application with ThemeProvider
Use ThemeProvider
to make the theme available to your component tree.
// App.js
import React from 'react';
import { ThemeProvider } from '@emotion/react';
import { theme } from './theme';
import MyComponent from './MyComponent';
function App() {
return (
<ThemeProvider theme={theme}>
<MyComponent />
</ThemeProvider>
);
}
export default App;
4. Access the Theme with useTheme
Use useTheme
hook to access the theme inside your components.
// MyComponent.js
import React from 'react';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
const ThemedDiv = styled.div`
background-color: ${props => props.theme.colors.primary};
padding: ${props => props.theme.spacing.medium};
color: white;
`;
function MyComponent() {
const theme = useTheme();
return (
<ThemedDiv>
This div is styled using the theme!
<p>The primary color is {theme.colors.primary}</p>
</ThemedDiv>
);
}
export default MyComponent;
Detailed Explanation
ThemeProvider
- Purpose: To provide a theme object to the component tree. - How it Works: It uses React Context internally to pass down the theme to all components within its subtree.
Example:
import React from 'react';
import { ThemeProvider } from '@emotion/react';
const theme = {
colors: {
primary: 'hotpink',
background: 'lightgray',
},
};
function App() {
return (
<ThemeProvider theme={theme}>
<div style={{ backgroundColor: theme.colors.background }}>
<h1 style={{ color: theme.colors.primary }}>Hello, Theme!</h1>
</div>
</ThemeProvider>
);
}
export default App;
useTheme
- Purpose: To access the theme object within functional components.
- How it Works: It retrieves the theme from the nearest ThemeProvider
using React's Context API.
Example:
import React from 'react';
import { useTheme } from '@emotion/react';
function ThemedComponent() {
const theme = useTheme();
return (
<div style={{ color: theme.colors.primary }}>
This text is using the primary color from the theme.
</div>
);
}
export default ThemedComponent;
Combining Both in a Real-World Scenario
You can use both ThemeProvider
and useTheme
to create a cohesive theming system for your application.
Example:
// theme.js
export const theme = {
colors: {
primary: 'hotpink',
secondary: 'green',
background: 'lightgray',
},
spacing: {
small: '8px',
medium: '16px',
large: '32px',
},
};
// App.js
import React from 'react';
import { ThemeProvider } from '@emotion/react';
import { theme } from './theme';
import ThemedComponent from './ThemedComponent';
function App() {
return (
<ThemeProvider theme={theme}>
<div style={{ backgroundColor: theme.colors.background }}>
<ThemedComponent />
</div>
</ThemeProvider>
);
}
export default App;
// ThemedComponent.js
import React from 'react';
import { useTheme } from '@emotion/react';
function ThemedComponent() {
const theme = useTheme();
return (
<div style={{ padding: theme.spacing.medium, color: theme.colors.primary }}>
This component is styled using the theme.
</div>
);
}
export default ThemedComponent;
Difference Between import { theme } from './theme';
and import { useTheme } from '@emotion/react';
Both import { theme } from './theme';
and import { useTheme } from '@emotion/react';
are used to work with themes in a React application, but they serve different purposes and come from different sources.
1. import { theme } from './theme';
- Source: This import statement typically comes from a custom file (e.g., theme.js
) where the theme object is defined.
- Purpose: The theme
object contains design tokens such as colors, spacing, typography, etc., which you define and use throughout your application.
- Usage: This is used to provide the theme object to the ThemeProvider
so that it can be made available to the entire component tree.
Example of theme.js
:
// theme.js
export const theme = {
colors: {
primary: 'hotpink',
secondary: 'green',
background: 'lightgray',
},
spacing: {
small: '8px',
medium: '16px',
large: '32px',
},
};
Example of using theme
with ThemeProvider
:
// App.js
import React from 'react';
import { ThemeProvider } from '@emotion/react';
import { theme } from './theme';
import ThemedComponent from './ThemedComponent';
function App() {
return (
<ThemeProvider theme={theme}>
<ThemedComponent />
</ThemeProvider>
);
}
export default App;
2. import { useTheme } from '@emotion/react';
- Source: This import statement comes from the @emotion/react
library.
- Purpose: useTheme
is a hook that allows functional components to access the theme object provided by ThemeProvider
.
- Usage: This hook is used within a component to get the current theme object and apply its values directly in the component's styles or logic.
Example of using useTheme
:
// ThemedComponent.js
import React from 'react';
import { useTheme } from '@emotion/react';
function ThemedComponent() {
const theme = useTheme();
return (
<div style={{ padding: theme.spacing.medium, color: theme.colors.primary }}>
This component is styled using the theme.
</div>
);
}
export default ThemedComponent;
Key Differences
1. Definition vs. Consumption:
- theme
is defined in your custom file (theme.js
) and contains all the design tokens.
- useTheme
is used to consume the theme object within functional components.
2. Usage Context:
- theme
is passed to ThemeProvider
to make the theme available throughout the app.
- useTheme
is used within components to access the theme object.
3. Source:
- theme
is imported from a custom file you create and define.
- useTheme
is imported from the @emotion/react
library.
Practical Example Combining Both
// theme.js
export const theme = {
colors: {
primary: 'hotpink',
secondary: 'green',
background: 'lightgray',
},
spacing: {
small: '8px',
medium: '16px',
large: '32px',
},
};
// App.js
import React from 'react';
import { ThemeProvider } from '@emotion/react';
import { theme } from './theme';
import ThemedComponent from './ThemedComponent';
function App() {
return (
<ThemeProvider theme={theme}>
<div style={{ backgroundColor: theme.colors.background }}>
<ThemedComponent />
</div>
</ThemeProvider>
);
}
export default App;
// ThemedComponent.js
import React from 'react';
import { useTheme } from '@emotion/react';
function ThemedComponent() {
const theme = useTheme();
return (
<div style={{ padding: theme.spacing.medium, color: theme.colors.primary }}>
This component is styled using the theme.
</div>
);
}
export default ThemedComponent;
References
- Emotion Documentation - Styled Components in Emotion - MDN Web Docs: React Context API