2016-11-29 20 views
13

我目前正在构建一个大的React应用程序。 Css从来不是我的强项。但是现在CSS有了React的sass/cssNext/inline样式。我一直在使用BEM和sass,但随着我的其他应用程序增长巨大,甚至开始崩溃。特别是当你有能力“重新皮肤”或“主题”以外的主要色彩配置等页面。与React的CSS架构,也可以为主题

所以 - 有人可以指点我一个经过验证的方式来创建css的反应,可以规模非常好,并允许客户主题时,人们想借我的组件。例如,

<MyComponent /> 
// this component has its styles but lets say Joe Schmoe wants be import 
// it? But, Joe wants to overlay his custom styles? 
// Is there a new paradigm that allows for an overlay or reskin within the component? 

甚至整个应用程序的构想都可以在一段时间后换肤。我知道这是一个非常基础的问题,但每当我构建项目时,我的痛点也似乎是CSS - 所以我想知道真正起作用的。

回答

20

直到最近,这还不是React世界中解决的问题。

我是ElementalUI(一个React组件库)的维护者之一,我们在过去的6-12个月里一直在尝试所有不同的样式化方法。 (!)你的名字,我们已经尝试过了。 (我在我的ReactNL keynote和他们分解的地方谈到了我对一些最流行的库的使用经验)

问题是,目前的样式库都没有内置的主题支持。你可以用一种非常好用的,非用户友好的方式来做到这一点,但是当你发布一个组件时,这不是你想要的,对吗?


这就是为什么我们建造了styled-componentsstyled-components有一些有趣的属性,其中一个是将主题直接内置到库中,使其成为构建可分发组件的完美选择!

下面是简短的解释,但我鼓励你通过我们的documentation解释一切!

这是什么styled-components的基本用法是这样的:

import React from 'react'; 
import styled from 'styled-components'; 

// Create a <Wrapper> react component that renders a <section> with 
// some padding and a papayawhip background 
const Wrapper = styled.section` 
    padding: 4em; 
    background: papayawhip; 
`; 

这个变量,Wrapper,现在反应的组分可以渲染:

// Use them like any other React component – except they're styled! 
<Wrapper> 
    <Title>Hello World, this is my first styled component!</Title> 
</Wrapper> 

What this looks like rendered

(如果你点击图像,你会得到一个现场操场)

当您将插值函数传递给带标签的模板文字时,我们将传递给该组件的属性传递给您。这意味着你可以适应道具:

import styled from 'styled-components'; 

const Button = styled.button` 
    /* Adapt the colors based on primary prop */ 
    background: ${props => props.primary ? 'palevioletred' : 'white'}; 
    color: ${props => props.primary ? 'white' : 'palevioletred'}; 

    font-size: 1em; 
    margin: 1em; 
    padding: 0.25em 1em; 
    border: 2px solid palevioletred; 
    border-radius: 3px; 
`; 

在这里,我们创建了一个Button组件,你可以做primary像任何其他阵营组成:

<Button>Normal</Button> 
<Button primary>Primary</Button> 

A normal button and a bigger primary button

现在来主题方面。我们出口一个名为ThemeProvider组件,您可以通过一个theme并包装您的应用程序(或应用程序的部分):该ThemeProvider

import { ThemeProvider } from 'styled-components'; 

const theme = { 
    main: 'mediumseagreen', 
}; 

ReactDOM.render(
    <ThemeProvider theme={theme}> 
    <MyApp /> 
    </ThemeProvider>, 
    myElem 
); 

现在,任何风格的组成部分,无论多么深刻的感谢背景下,将把这个theme注入道具。

这是一个主题化Button会是什么样子:

import styled from 'styled-components'; 

const Button = styled.button` 
    /* Color the background and border with theme.main */ 
    background: ${props => props.theme.main}; 
    border: 2px solid ${props => props.theme.main}; 

    /* …more styles here… */ 
`; 

现在你Button会把它被传递的theme并改变它基于这样的造型! (您也可以通过defaultProps提供默认设置)

这就是styled-components的要点,以及它如何帮助构建可分发的组件!

我们目前有WIP doc about writing third-party component libraries,我鼓励您查看,当然,正常的文档也是一个很好的阅读。我们试图涵盖所有的基础,所以如果你看到任何你不喜欢的或者你认为失踪的东西,请马上告诉我们,我们将讨论!

如果您有任何其他关于styled-components的问题,请随时在此回复或在Twitter上与我们联系。 (@mxstbr

+0

你如何定制你自己的自定义组件? 只需使用div包装? – MoeSattler

+0

是的,我使用每个较大组件的大量样式化组件。类似这样的: const Btn =风格。按钮' 风格:这里; ' const的按钮=(道具)=> { 回报( {props.text} ); } – mxstbr

+0

如何解决组件中样式的实际耦合问题。例如,让我们说我的所有按钮现在都需要5px的半径,我必须进入所有按钮并手动更改它们。或者我读你的帖子是错的?或媒体查询,你如何使用它们? –

1

我不知道什么是最好的方法。我认为这更像个人喜好。我只会分享我正在使用的工具。我正在使用的是css-modulespostcss

css-modules使您可以为每个CSS类创建一个全局唯一名称的本地范围标识符,并且还可以启用模块化和可重用的CSS!您也可以使用postcss-modules-values创建一个包含所有设置变量的全局设置文件。所以你可以改变你的网站的主题。

下面是我如何构造组件。我的每个组件都有一个非常容易维护或更改的css文件。

enter image description here

这里的Button组件的代码。

function Button(props) { 
    const className = props.className ? `${styles.button} ${props.className}` : styles.button; 

    return (
    <button disabled={props.disabled} className={`${className}`} type="button" onClick={props.onClick}> 
     {Children.toArray(props.children)} 
    </button> 
); 
} 

请注意,我有一个允许其他组件在类中传递按钮组件的className。所以当有人借用你的组件时,他们可以扩展或覆盖你的按钮样式。

如果您需要创建可自定义的网站,我也会推荐使用Less.js,它提供了自定义网站的实时预览。