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的更多相关文章

  1. [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 ...

  2. react初探索--react + react-router + ant-design 后台管理系统配置

    首先确认安装了node环境,Node >= 6. 如果对react 及 ant-design 一无所知,建议去阅读下api文档,react 可以在 codePen 在线练习. react Api ...

  3. react新特性 react hooks

    本文介绍的是react新特性react hooks,本文面向的是有一定react开发经验的小伙伴,如果你对react还不是很熟悉的话我建议你先学习react并多多联系. 首先我们都知道react有3种 ...

  4. [react] 细数 React 的原罪

    Props & onChange 的原罪 .「props & onChange 接口规范」它不是一个典型的「程序接口规范」. 当你拿到一个可视组件的 ref,却没有类似 setProp ...

  5. React笔记:React基础(2)

    1. JSX JSX是一种拥有描述UI的JavaScript扩展语法,React使用这种语法描述组件的UI. 1.1 基本语法 JSX可以嵌套多个HTML标签,可以使用大部分符号HTML规范的属性. ...

  6. 【React Native】React Native项目设计与知识点分享

    闲暇之余,写了一个React Native的demo,可以作为大家的入门学习参考. GitHub:https://github.com/xujianfu/ElmApp.git GitHub:https ...

  7. react聊天室|react+redux仿微信聊天IM实例|react仿微信界面

    一.项目概况 基于react+react-dom+react-router-dom+redux+react-redux+webpack2.0+react-photoswipe+swiper等技术混合开 ...

  8. React源码 React.Component

    React中最重要的就是组件,写的更多的组件都是继承至 React.Component .大部分同学可能都会认为 Component 这个base class 给我们提供了各种各样的功能.他帮助我们去 ...

  9. 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 ...

随机推荐

  1. 三菱FX系列PLC学习

    1.PLC工作原理 PLC将程序存储在用户存储器当中, 驱动其运行, 相对比微型计算机软件, PLC程序则不同的是, 微型计算机整个流程则是从规定的开始 至结束完整工作流程.相对与PLC运行,则是从位 ...

  2. 【Spring】Service 注入失败,空指针

    service层的类都有用@Service标识,但报空指针,注入失败,很可能是因为spring的application配置和springmvc的配置文件配置错误,导致容器冲突了. spring和spr ...

  3. teamviewer连接不上的原因及解决方法有哪些

    teamviewer连接不上的原因及解决方法有哪些 一.总结 一句话总结:这里说的就是版本问题,高版本可以连接低版本,低版本无法连接高版本. 1.TeamViewer官方检测使用环境是否为商用的标准是 ...

  4. cv2.putText 文字换行('\n')无法解析换行

    OpenCV putText() new line character cv2.putText 在向图像中添加文本信息时,如果在待添加的文本中含有换行转义符,一般它是无法正确处理的: cv2.putT ...

  5. IIS7性能优化

    http://www.03389.com/BLOG/user1/qq66565841/archives/2014/2014112143553.html IIS7性能优化 IIS7 优化-网站请求并发数 ...

  6. 83.#pragma详解

    创建数据段 //创建数据段 #pragma data_seg("fangfangdata") ; #pragma data_seg() 与数据段连接,实现数据通信,分享 //实现数 ...

  7. GO语言学习(十八)Go 语言接口

    Go 语言接口 Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口. 实例 /* 定义接口 */ type interface ...

  8. 未能加载文件或程序集“System.Collections.Concurrent”或它的某一个依赖项。

    未能加载文件或程序集“XXXXXX”或它的某一个依赖项.试图加载格式不正确的程序.   在本机WIN7机器上的WebService部署到Win2008R2上发现错误 “/”应用程序中的服务器错误. 未 ...

  9. Day2:购物车小程序

    一.购物车小程序第一版 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Hiuhung Wan product_list = [ (&quo ...

  10. GO语言学习(六)Go 语言数据类型

    在 Go 编程语言中,数据类型用于声明函数和变量. 数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存. Go 语言按类别有以下几种 ...