我知道如何从使用theme
方式创建的组件中获取styled
:
const StyledView = styled.View`
color: ${({ theme }) => theme.color};
`;
但是如何从普通组件获取或将其应用于不同的属性?例如:
index.js
<ThemeProvider theme={{ color: 'red' }}>
<Main />
</ThemeProvider>
main.js
<View>
<Card aCustomColorProperty={GET COLOR FROM THEME HERE} />
</View>
注意不需要主题的属性
style
答案 0 :(得分:10)
您可以使用 useTheme
钩子
import { useTheme } from 'styled-components';
const ExampleComponent = () => {
const theme = useTheme();
return (
<View>
<Card aCustomColorProperty={theme.color.sampleColor} />
</View>
);
};
答案 1 :(得分:8)
编辑:从v1.2开始,我的拉取请求已合并,你可以使用 这种withTheme高阶组件:
import { withTheme } from 'styled-components'
class MyComponent extends React.Component {
render() {
const { theme } = this.props
console.log('Current theme: ', theme);
// ...
}
}
export default withTheme(MyComponent)
下面的原帖
我现在提出的解决方案:
创建一个更高阶的组件,负责获取当前主题并作为道具传递给组件:
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} />
}
}
然后,在您需要访问theme
:
import Themable from './Themable.js'
const Component = ({ theme }) => <Card color={theme.color} />
export default Themable(Component);
答案 2 :(得分:0)
创建HOC是解决主题的好方法。让我分享另一个想法,使用 React的 Context。
Context允许您将数据从父节点传递给它的所有子节点。
每个孩子都可以通过在组件定义中定义context
来选择访问contextTypes
。
假设 App.js 是您的根。
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;
现在我们的` ChildComponent.js 想要一些主题和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 谁只想要主题而不是i18n。他也可能是无国籍的:
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;
答案 3 :(得分:0)
要在功能组件中使用withTheme
,请创建一个高阶组件。
高阶组件: 高阶组件或 HOC 是获取组件并在以某种方式对其进行增强后输出新组件的函数:
const EnhancedHOCComponent = hoc(OriginalReactComponent)
const MyButton = ({theme}) => {
const red = theme.colors.red;
return (<div style={{ color: red}} >how are you</div>)
}`
const Button = withTheme(MyButton);
export default Button;