[React] Recompose: Theme React Components Live with Context
SASS Bootstrap allows us to configure theme or branding variables that affect all components (e.g. Primary Color or Link Color). When we isolate our styles inside React components we lose the ability to theme them. To get round this we can put our theme variables on the context of our app and then read them from individual components in order to make styling decisions. Recompose allows us to create the helper functions we need to do this yielding concise, functional declarative UI components. These components will respond in real time to changes in the theme.
We have a default theme file:
export default {
color: {
keyColor: '#3f8bae',
textLight: '#fff',
},
number: {
buttonRadius: 5
},
string: {
mainFontFamily: 'sans-serif'
}
}
We want Component get defualt theme according to the file.
We will build an interface to update theme according to user input.

We can import theme file into the App.js compoent and pass down to the custom component. The problem is that, if we have hunders components, it is not ideal to passdown the props hundres times.
That's why we need context.
We can use 'recompose' to do that:
import React, { Component } from 'react';
import {compose, withState} from 'recompose';
import myDefaultTheme from './themes/default';
import Button from './components/Button';
class App extends Component {
static childContextTypes = {
theme: React.PropTypes.object
};
getChildContext() {
return {theme: this.props.theme}
}
render() {
const {theme, updateTheme} = this.props;
return (
<div className="App">
<main className="container">
...
</main>
</div>
);
}
}
const enhance = compose(
withState('theme', 'updateTheme', myDefaultTheme)
);
export default enhance(App);
So for this part of code:
const enhance = compose(
withState('theme', 'updateTheme', myDefaultTheme)
);
export default enhance(App);
We wrap our App component with 'enhance' to update component props.
widthState function: Passes two additional props to the base component: a state value, and a function to update that state value. so 'updateTheme' will take nextProps to udpate current props.
static childContextTypes = {
theme: React.PropTypes.object
};
getChildContext() {
return {theme: this.props.theme}
}
Those code helps us to pass 'theme' down to children components.
Also need to create a file called "hocs.js" which means high order component. This file contains reusable methods to update the custom component.
To get context from 'App.js', we need 'getContext' method form 'recompose':
export const getTheme = getContext({
theme: PropTypes.shape({
color: PropTypes.object,
number: PropTypes.object,
string: PropTypes.object
})
});
We also need a 'themeStyle' method to update style:
export const themeStyle = mapThemeToStyle => mapProps(
props => {
const { theme, style } = props; return {
...props,
style: [
mapThemeToStyle(theme, props),
style
]
};
}
);
It takes a updater function called 'mapThemeToStyle' which can map theme to style according to different components needs.
Now in the custom component, let compose those:
import React from 'react';
import {
mapProps,
compose,
defaultProps,
setDisplayName,
componentFromProp
} from 'recompose';
import Radium from 'radium'; import {
getTheme,
themeStyle,
addStyle
} from './hocs'; const mapThemeToStyle = ({
color,
number,
string
}) => {
return {
...(color.keyColor &&
{backgroundColor: color.keyColor} || {}
),
color: color.textLight,
borderRadius: number.buttonRadius,
fontFamily: string.mainFontFamily
};
}; const style = {
backgroundColor: 'red',
borderWidth: ,
borderStyle: 'solid',
boxSizing: 'border-box',
fontFamily: 'sans-serif',
fontSize: ,
borderRadius: ,
fontWeight: ,
padding: ,
verticalAlign: 'middle',
whiteSpace: 'nowrap',
color: 'white',
alignItems: 'center',
justifyContent: 'center',
textDecoration: 'none',
display: 'flex',
flex: ,
cursor: 'pointer',
':hover': {
backgroundColor: 'purple'
}
}; const enhance = compose(
getTheme, // using the container's defined theme
themeStyle(mapThemeToStyle), // apply the default theme to the component
addStyle(style),
setDisplayName('Button'),
defaultProps({
element: 'button'
}),
Radium
);
export default enhance(componentFromProp('element'));
[React] Recompose: Theme React Components Live with Context的更多相关文章
- [React] Render Text Only Components in React 16
In this session we create a comment component to explore how to create components that only render t ...
- react初探索--react + react-router + ant-design 后台管理系统配置
首先确认安装了node环境,Node >= 6. 如果对react 及 ant-design 一无所知,建议去阅读下api文档,react 可以在 codePen 在线练习. react Api ...
- react新特性 react hooks
本文介绍的是react新特性react hooks,本文面向的是有一定react开发经验的小伙伴,如果你对react还不是很熟悉的话我建议你先学习react并多多联系. 首先我们都知道react有3种 ...
- [react] 细数 React 的原罪
Props & onChange 的原罪 .「props & onChange 接口规范」它不是一个典型的「程序接口规范」. 当你拿到一个可视组件的 ref,却没有类似 setProp ...
- React笔记:React基础(2)
1. JSX JSX是一种拥有描述UI的JavaScript扩展语法,React使用这种语法描述组件的UI. 1.1 基本语法 JSX可以嵌套多个HTML标签,可以使用大部分符号HTML规范的属性. ...
- 【React Native】React Native项目设计与知识点分享
闲暇之余,写了一个React Native的demo,可以作为大家的入门学习参考. GitHub:https://github.com/xujianfu/ElmApp.git GitHub:https ...
- react聊天室|react+redux仿微信聊天IM实例|react仿微信界面
一.项目概况 基于react+react-dom+react-router-dom+redux+react-redux+webpack2.0+react-photoswipe+swiper等技术混合开 ...
- React源码 React.Component
React中最重要的就是组件,写的更多的组件都是继承至 React.Component .大部分同学可能都会认为 Component 这个base class 给我们提供了各种各样的功能.他帮助我们去 ...
- WHAT IS THE DIFFERENCE BETWEEN REACT.JS AND REACT NATIVE?
Amit Ashwini - 09 SEPTEMBER 2017 React.js was developed by Facebook to address its need for a dynami ...
随机推荐
- WPF 入门《常用控件》
1.GroupBox 注意: GroupBox仍然需要布局容器来放置元素.如: StackPanel面板 <GroupBox Header="select number?"& ...
- RFID的基本组织构成
RFID技术由3大组件构成, 包括: 阅读器.天线.标签三大组件. 阅读器 为RFID系统最重要也是最复杂的一个组件.因其工作模式一般是主动向标签询问标识信息, 所以有时又被称为询问器(Interro ...
- Linux 网卡驱动学习(九)(层二转发)
1.mac 地址表的自学习过程 port1上的A计算机要与port2上的B计算机通信时,A发到交换机上,交换机收到信息后,交换机先记录发port1所相应的a的mac地址并记录在自己的mac表中,然后再 ...
- vue实现一个会员卡的组件(可以动态传入图片(分出的一个组件)、背景、文字、卡号等)
自己在写这个组件的时候主要遇到的问题就是在动态传入背景图片或者背景色的时候没能立马顺利写出来,不过现在实现了这个简单组件就和大家分享一下 <template> <div class= ...
- request.getRemoteUser() Spring Security做权限控制后
一. request.getRemoteUser();//获取当前缓存的用户,比如Spring Security做权限控制后就会将用户登录名缓存到这里 request.getRemoteAddr(); ...
- 调色板原理 & 编程
调色板原理 & 编程 逻辑调色板结构LOGPALETTE,该结构定义如下: typedef struct tagLOGPALETTE { WORD palVersion; //调色板的板本号, ...
- 通达OA二次开发 对通达2015版微信查询用户信息模块升级开发(图文)
OA提供对微信的支持这一点做的很好,用户使用起来也更方便了. 而当中的个别功能还有待完好,比现在天要说的这个微信查询用户信息模块. 升级前的用法:输入@+用户中文名.而且要求全然匹配,然而在实际使用中 ...
- 深入并发AQS二
AQS须要解决下面几个问题: 1.锁状态,怎样保证并发情况下可以安全的更新? 2.当前线程不能获取锁时,放在哪里? AQS是放在一个队列其中 3.怎样提高效率? AQS的主要职责是当获取不到锁时.将线 ...
- 如何使用 PyCharm 将代码上传到GitHub上(详细图解)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 一丶说明 测试条件:需要有GitHub账号以及在本地安装了Git工具,无论是Linux环境还是Windows都是一样的 如果还没有 ...
- 互信息 & 卡方 - 文本挖掘
在做文本挖掘,特别是有监督的学习时,常常需要从文本中提取特征,提取出对学习有价值的分类,而不是把所有的词都用上,因此一些词对分类的作用不大,比如“的.是.在.了”等停用词.这里介绍两种常用的特征选择方 ...