How to get a theme out of stylish components?

I know how to get the theme from components created using the styled method:

 const StyledView = styled.View` color: ${({ theme }) => theme.color}; `; 

But how to get from ordinary components or apply it for different properties ? Example:

index.js

 <ThemeProvider theme={{ color: 'red' }}> <Main /> </ThemeProvider> 

main.js

 <View> <Card aCustomColorProperty={GET COLOR FROM THEME HERE} /> </View> 

Note that a property that needs a theme is not called style

+7
reactjs react-native styled-components
source share
2 answers

EDIT: Starting with version 2.1, my stretch request has been merged, and you can use a higher-order component withTheme as follows:

 import { withTheme } from 'styled-components' class MyComponent extends React.Component { render() { const { theme } = this.props console.log('Current theme: ', theme); // ... } } export default withTheme(MyComponent) 

original post below

The solution I came to now:

Create a component of a higher order, which will be responsible for obtaining the current topic and passed as a support for the component:

 import React from 'react'; import { CHANNEL } from 'styled-components/lib/models/ThemeProvider'; export default Component => class extends React.Component { static contextTypes = { [CHANNEL]: React.PropTypes.func, }; state = { theme: undefined, }; componentWillMount() { const subscribe = this.context[CHANNEL]; this.unsubscribe = subscribe(theme => { this.setState({ theme }) }); } componentWillUnmount() { if (typeof this.unsubscribe === 'function') this.unsubscribe(); } render() { const { theme } = this.state; return <Component theme={theme} {...this.props} /> } } 

Then call it on the component that you need to access the theme :

 import Themable from './Themable.js' const Component = ({ theme }) => <Card color={theme.color} /> export default Themable(Component); 
+5
source share

Creating an HOC is a good way to handle the topic. Let me share another idea using React Context .

The context allows you to pass data from the parent node to all its children. Each child can choose context access by defining contextTypes in the component definition.

Let's say App.js is your root.

 import themingConfig from 'config/themes'; import i18nConfig from 'config/themes'; import ChildComponent from './ChildComponent'; import AnotherChild from './AnotherChild'; class App extends React.Component { getChildContext() { return { theme: themingConfig, i18n: i18nConfig, // I am just showing another common use case of context } } render() { return ( <View> <ChildComponent /> <AnotherChild myText="hola world" /> </View> ); } } App.childContextTypes = { theme: React.PropTypes.object, i18n: React.PropTypes.object }; export default App; 

Now our ` ChildComponent.js , who wants some theme and lines i18n

 class ChildComponent extends React.Component { render() { const { i18n, theme } = this.context; return ( <View style={theme.textBox}> <Text style={theme.baseText}> {i18n.someText} </Text> </View> ); } } ChildComponent.contextTypes = { theme: React.PropTypes.object, i18n: React.PropTypes.object }; export default ChildComponent; 

AnotherChild.js , which wants only a theme, but not i18n. It can also be stateless:

 const AnotherChild = (props, context) { const { theme } = this.context; return (<Text style={theme.baseText}>{props.myText}</Text>); } AnotherChild.propTypes = { myText: React.PropTypes.string }; AnotherChild.contextTypes = { theme: React.PropTypes.object }; export default AnotherChild; 
0
source share

All Articles