useTheme

Creating and using theme values.

The hook for themes allows you to access theme values at runtime. If you use any of its values for style properties, the compiler will attempt to optimize them on the web. On native, theme values are left in the render function, if React Native supports themes at some point we could compile to that.

You can mix and match the media query hook and inline style syntaxes as well:

import { YStack, useMedia, useTheme } from 'tamagui'
const App = () => {
const theme = useTheme()
const media = useMedia()
return (
<YStack y={media.sm ? 10 : 0} backgroundColor={media.lg ? theme.red : theme.blue} {...(media.xl && { y: theme.space2, })} />
)
}

This will compile on the web to:

const _cn =
' _alignItems-1oszu61 _boxSizing-deolkf _display-6koalj _flexBasis-1mlwlqe _flexDirection-eqz5dr _flexShrink-1q142lx _transform-_sm_1exagq _transform-_sm0_1wpzndr _backgroundColor-_lg_no4z4g _backgroundColor-_lg0_1qoifqd _transform-_xl_gqa6p0'
import { YStack, useMedia, useTheme } from 'tamagui'
const App = () => {
return <div className={_cn} />
}

And the following CSS:

._alignItems-1oszu61 {
-ms-flex-align: stretch;
-webkit-align-items: stretch;
-webkit-box-align: stretch;
align-items: stretch;
}
._boxSizing-deolkf {
box-sizing: border-box;
}
._display-6koalj {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
._flexBasis-1mlwlqe {
-ms-flex-preferred-size: auto;
-webkit-flex-basis: auto;
flex-basis: auto;
}
._flexDirection-eqz5dr {
-ms-flex-direction: column;
-webkit-box-direction: normal;
-webkit-box-orient: vertical;
-webkit-flex-direction: column;
flex-direction: column;
}
._flexShrink-1q142lx {
-ms-flex-negative: 0;
-webkit-flex-shrink: 0;
flex-shrink: 0;
}
@media screen and (max-width: 860px) {
:root:root ._transform-_sm_1exagq {
-webkit-transform: translateY(10px);
transform: translateY(10px);
}
}
@media not all and (max-width: 860px) {
:root:root ._transform-_sm0_1wpzndr {
-webkit-transform: translateY(0px);
transform: translateY(0px);
}
}
@media screen and (min-width: 1120px) {
:root:root:root ._backgroundColor-_lg_no4z4g {
background-color: var(--red);
}
}
@media not all and (min-width: 1120px) {
:root:root:root ._backgroundColor-_lg0_1qoifqd {
background-color: var(--blue);
}
}
@media screen and (min-width: 1280px) {
:root:root:root:root ._transform-_xl_gqa6p0 {
-webkit-transform: translateY(var(--space2));
transform: translateY(var(--space2));
}
}

Using outside of styling

Yes. The nice thing about useTheme and useMedia is that they fall back gracefully and can be used generally in your render for any purpose. Like useMedia, if you use useTheme like this, it also granularly tracks which values you use and only re-renders on tracked keys.

So if you access only theme.bg in your render function, the component will only re-render when theme.bg changes.

Changing the theme at the hook level

This is a more advanced use for building custom hooks or components, but you can pass in a theme name and a component theme name (as discussed here) to grab the right subset theme:

function MyComponent(props) {
const theme = useTheme(props.theme, 'MyComponent')
}

For example, if you have the following themes:

  • dark
  • dark_green
  • dark_green_MyComponent

And this code:

<Theme name="dark">
<MyComponent theme="green" />
</Theme>

The above useTheme hook would return the dark_green_MyComponent theme.