[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: 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‘));
时间: 2024-10-14 06:54:47

[React] Recompose: Theme React Components Live with Context的相关文章

react新特性 react hooks

本文介绍的是react新特性react hooks,本文面向的是有一定react开发经验的小伙伴,如果你对react还不是很熟悉的话我建议你先学习react并多多联系. 首先我们都知道react有3种组件:分别是Function函数式无状态组件.class有状态组件.高阶组件.这里不对这3种组件做一一介绍. 本文重点是react hooks 一个最简单的Hooks 首先让我们看一下一个简单的有状态组件: 1 class Example extends React.Component { 2 co

【玩转React】关于React你需要知道的事儿

前言 随着前端技术的迅猛发展,各种前端框架也随势崛起,但归根结底,支撑每一款web框架流行的强大因素都是它能更好地服务于业务. React 自然也不例外,它的开发者当初正在开发Facebook的一个广告系统,由于不满足于当下任何的 MVC 框架,所以就自己写了一套 UI 框架,于是乎大名鼎鼎的 React 就由此诞生了. React 的出现无疑为 web 开发带来了颠覆性的改变,多少开发者夜以继日只为体验一把 React 带来的快感.本文就将带领大家一起领略一番 React 的理念.特色与情怀.

[React] Style a React component with styled-components

In this lesson, we remove the mapping between a React component and the styles applied to it via classnames. We write our styles directly within the component, in a real CSS syntax, with the full power of JavaScript. Old: import React, { Component }

创建React工程:React工程模板

这是本人初学React做的学习笔记;讲的不是很深,只算是简单的进行介绍. 这是一个小系列.都是在同一个模板中搭建的,但是代码是不能正常执行的. >>index.js <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>React工程模板</title> <!-- react.js 是Reac

React Native之React速学教程(下)

概述 本篇为<React Native之React速学教程>的最后一篇.本篇将带着大家一起认识ES6,学习在开发中常用的一些ES6的新特性,以及ES6与ES5的区别,解决大家在学习React /React Native过程中对于ES6与ES5的一些困惑. ES6的特性 何为ES6? ES6全称ECMAScript 6.0,ES6于2015年6月17日发布,ECMAScript是ECMA制定的标准化脚本语言.目前JavaScript使用的ECMAScript版本为ECMAScript-262.

React Native之React速学教程(上)

概述 本篇为<React Native之React速学教程>的第一篇.本篇将从React的特点.如何使用React.JSX语法.组件(Component)以及组件的属性,状态等方面进行讲解. What's React React是一个用于组建用户界面的JavaScript库,让你以更简单的方式来创建交互式用户界面. 当数据改变时,React将高效的更新和渲染需要更新的组件.声明性视图使你的代码更可预测,更容易调试. 构建封装管理自己的状态的组件,然后将它们组装成复杂的用户界面.由于组件逻辑是用

React Native之React速学教程(中)

概述 本篇为<React Native之React速学教程>的第一篇.本篇将从React的特点.如何使用React.JSX语法.组件(Component)以及组件的属性,状态等方面进行讲解. What's React React是一个用于组建用户界面的JavaScript库,让你以更简单的方式来创建交互式用户界面. 当数据改变时,React将高效的更新和渲染需要更新的组件.声明性视图使你的代码更可预测,更容易调试. 构建封装管理自己的状态的组件,然后将它们组装成复杂的用户界面.由于组件逻辑是用

为什么要学习React,学习React在大数据开发上有什么好处

为什么要学习React,学习React在大数据开发上有什么好处 分享之前我还是要推荐下我自己创建的大数据学习资料分享群716581014,这是全国最大的大数据学习交流的地方,2000人聚集,不管你是小白还是大牛,小编我都挺欢迎,今天的源码已经上传到群文件,不定期分享干货,包括我自己整理的一份最新的适合2018年学习和零基础入门教程,欢迎初学和进阶中的小伙伴. 如何学习React 如果你是一个 React (或者前端) 新手, 出于以下的原因, 你可能会对这个生态圈感到困惑: React 的目标群

React.Component 与 React.PureComponent(React之性能优化)

前言 先说说 shouldComponentUpdate 提起React.PureComponent,我们还要从一个生命周期函数 shouldComponentUpdate 说起,从函数名字我们就能看出来,这个函数是用来控制组件是否应该被更新的. React.PureComponent 通过prop和state的浅对比来实现shouldComponentUpate(). 简单来说,这个生命周期函数返回一个布尔值. 如果返回true,那么当props或state改变的时候进行更新: 如果返回fal