使用主题
Emotion的主题功能是在@emotion/react
库中提供的,跟React的Context一样,主题功能也是需要使用<ThemeProvider>
在全局提供目前要使用的主题,然后在组件树的枝叶部分就可以使用props
、withTheme()
或者useTheme()
来使用主题,并在主题发生变化的时候使组件发生重新渲染。
<ThemeProvider>
使用theme
属性接受一个对象来作为主题。这个用于定义主题的对象,其中都是由样式属性组成,这些样式属性的值将构成所有组件中对应样式属性的默认值。一个应用中<ThemeProvider>
可以使用多个,而且不同主题之间定义的相同样式属性之间会根据<ThemeProvider>
之间的层级关系产生覆盖。
例如以下示例。
import { ThemeProvider } from '@emotion/react';
const theme = {
backgroundColor: 'gray',
color: 'red'
};
const adjustTheme = ancestorTheme => ({ ...ancestorTheme, color: 'blue' });
function Container() {
return (
<ThemeProvider theme={theme}>
<ThemeProvider theme={adjustTheme}>
<p>Some text.</p>
</ThemeProvider>
</ThemeProvider>
);
}
在组件中应用主题可以通过两个途径,一个是使用withTheme
函数定义高阶组件,一个是使用useTheme
Hook。withTheme
可以将主题的配置注入到组件的this.props.theme
中。例如以下示例。
import React from 'react';
import { jsx, ithTheme } from '@emotion/react';
class Container extends React.Component {
render() {
return (
<div
css={{
color: this.props.theme.color
}}>
Some text.
</div>
);
}
}
const ContainerWithTheme = withTheme(Container);
在使用React新的Hook语法的时候,useTheme
就可以用来把主题设置引入组件。例如可以把上面这个示例改成以下样子。
import { jsx, ThemeProvider, useTheme } from '@emotion/react';
const theme = {
colors: {
primary: 'red'
}
};
function TextWithTheme(props) {
const theme = useTheme();
return <div css={{ color: theme.colors.primary }}>Some text.</div>;
}
function App() {
return (
<ThemeProvider theme={theme}>
<TextWithTheme />
</ThemeProvider>
);
}