博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[React] Recompose: Theme React Components Live with Context
阅读量:4319 次
发布时间:2019-06-06

本文共 5074 字,大约阅读时间需要 16 分钟。

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 (            
...
); }}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: 0,    borderStyle: 'solid',    boxSizing: 'border-box',    fontFamily: 'sans-serif',    fontSize: 18,    borderRadius: 3,    fontWeight: 100,    padding: 12,    verticalAlign: 'middle',    whiteSpace: 'nowrap',    color: 'white',    alignItems: 'center',    justifyContent: 'center',    textDecoration: 'none',    display: 'flex',    flex: 1,    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'));

 

转载于:https://www.cnblogs.com/Answer1215/p/6523001.html

你可能感兴趣的文章
cocos2dx 编辑框 CCEditBox
查看>>
第一节:ASP.NET开发环境配置
查看>>
PHP全栈学习笔记7
查看>>
表单脚本基础知识
查看>>
开源分享 Unity3d客户端与C#分布式服务端游戏框架
查看>>
浏览器默认缓存时间-(为什么浏览器时而缓存,时而不缓存)
查看>>
2013年最佳的16个 Photoshop 设计教程推荐
查看>>
15个优秀的 Material Design(材料设计)案例
查看>>
sql 列转行
查看>>
Html5 手机端网页不允许缩放
查看>>
Myeclipse 常用操作(待补充)
查看>>
PHP 获取当前所在的类名、方法名等
查看>>
基本数据类型和引用类型
查看>>
关于移动端APP开发-字体样式变大问题
查看>>
leetcode4568
查看>>
First 5 Minutes Troubleshooting A Server
查看>>
sqlserver database常用命令
查看>>
rsync远程同步的基本配置与使用
查看>>
第二天作业
查看>>
访问属性和访问实例变量的区别
查看>>