styled-component提供<ThemeProvider>包裝組件以支持主題.<ThemeProvider>通過contextAPI 為其后代組件提供主題.在其渲染樹中的所有組件都能夠訪問主題.
下面的示例通過創(chuàng)建一個(gè)按鈕組件來說明如何傳遞主題:
// Define our button, but with the use of props.theme this time const Button = styled.button` font-size: 1em; margin: 1em; padding: 0.25em 1em; border-radius: 3px; /* Color the border and text with theme.main */ color: ${props => props.theme.main}; border: 2px solid ${props => props.theme.main}; `; // We are passing a default theme for Buttons that arent wrapped in the ThemeProvider Button.defaultProps = { theme: { main: "palevioletred" } } // Define what props.theme will look like const theme = { main: "mediumseagreen" }; render( <div> <Button>Normal</Button> <ThemeProvider theme={theme}> <Button>Themed</Button> </ThemeProvider> </div> );
theme prop 也可以傳遞一個(gè)函數(shù).該函數(shù)接收渲染樹上級<ThemeProvider>所傳遞的主題. 通過這種方式可以使 themes 形成上下文.
下面的示例說明了如何通過第二個(gè)<ThemeProvider>來交換 background和foreground的顏色. 函數(shù)invertTheme 接收上級 theme 后創(chuàng)建一個(gè)新的 theme.
// Define our button, but with the use of props.theme this time const Button = styled.button` color: ${props => props.theme.fg}; border: 2px solid ${props => props.theme.fg}; background: ${props => props.theme.bg}; font-size: 1em; margin: 1em; padding: 0.25em 1em; border-radius: 3px; `; // Define our `fg` and `bg` on the theme const theme = { fg: "palevioletred", bg: "white" }; // This theme swaps `fg` and `bg` const invertTheme = ({ fg, bg }) => ({ fg: bg, bg: fg }); render( <ThemeProvider theme={theme}> <div> <Button>Default Theme</Button> <ThemeProvider theme={invertTheme}> <Button>Inverted Theme</Button> </ThemeProvider> </div> </ThemeProvider> );
如果需要在styled-components外使用主題,可以使用高階組件withTheme:
import { withTheme } from 'styled-components' class MyComponent extends React.Component { render() { console.log('Current theme: ', this.props.theme) // ... } } export default withTheme(MyComponent)
主題可以通過theme prop傳遞給組件.通過使用theme prop可以繞過或重寫ThemeProvider所提供的主題.
// Define our button const Button = styled.button` font-size: 1em; margin: 1em; padding: 0.25em 1em; border-radius: 3px; /* Color the border and text with theme.main */ color: ${props => props.theme.main}; border: 2px solid ${props => props.theme.main}; `; // Define what main theme will look like const theme = { main: "mediumseagreen" }; render( <div> <Button theme={{ main: "royalblue" }}>Ad hoc theme</Button> <ThemeProvider theme={theme}> <div> <Button>Themed</Button> <Button theme={{ main: "darkorange" }}>Overidden</Button> </div> </ThemeProvider> </div> );
更多建議: