[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 ...
随机推荐
- 【例题 8-10 UVA - 714】 Copying Books
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 二分最后的最大值的最小值. 得到ans 然后从后往前尽量划分. 如果发现不够分成k个. 那么就从第一个开始接着分restk个(每隔1 ...
- 洛谷——P1012 拼数
https://www.luogu.org/problem/show?pid=1012#sub 题目描述 设有n个正整数(n≤20),将它们联接成一排,组成一个最大的多位整数. 例如:n=3时,3个整 ...
- subline Text3 安装及汉化
因为自己的subline 有问题 所以决心重新改一下了. 三步: http://www.sublimetext.com/3 官网下载subline3 https://www.imjeff. ...
- 关于ES6(ES2015)的知识点详细总结
ECMAScript6 ECMAScript简称就是ES,你可以把它看成是一套标准,JavaScript就是实施了这套标准的一门语言,现在主流浏览器使用的是ECMAScript5. http://ba ...
- javasciprt cookies 操作
<script type="text/javascript"> function getCookie(c_name){ if (document.cookie.leng ...
- echarts+百度地图+vue 填坑记(一)(百度地图、鼠标移入移出标注,信息框会产生闪烁)
大概七月底开始实习,到现在经历了两个完整的项目(c2b). 因为开发时间紧,任务重,所以在开发过程踩到的坑都没时间去记录. 现在在开发一个某链运输监控系统,到了收尾阶段,有时间写博客了!开心! 一.鼠 ...
- 2013腾讯编程马拉松初赛第〇场(HDU 4504)威威猫系列故事——篮球梦
http://acm.hdu.edu.cn/showproblem.php?pid=4504 题目大意: 篮球赛假如我们现在已经知道当前比分 A:B,A代表我方的比分,B代表对方的比分,现在比赛还剩下 ...
- oracle主机名修改
转自:http://www.cnblogs.com/tippoint/archive/2013/04/07/3003810.html 有的情况下,我们需要修改已经安装oracle数据库的主机名.以下是 ...
- 【Codeforces Round #301 (Div. 2) C】 Ice Cave
[链接] 我是链接,点我呀:) [题意] 给你一个n*m的地图. 每个地图为0的时候可以安全走过,且走过后变成1. (一定要离开之后才会变成1) 而为1的则走过之后会掉入下一层. 你一开始在初始位置( ...
- git的安装及其使用
在Windows上安装Git的快捷方式: 工具:1.Windows的console工具:ConEmu(https://conemu.github.io/)多窗口.记录log.多theme选择,操作Gi ...