在你的React组件中使用CSS-in-JavaScript,无需紧密耦合到一种实现方式(例如 Aphrodite、Radium 或 React Native)。在定义样式时轻松访问共享主题信息(例如颜色、字体)。
创建一个模块,导出一个包含共享主题信息(如颜色)的对象。
export default {
color: {
primary: '#FF5A5F',
secondary: '#00A699',
},
};
注册你的主题和接口。例如,如果你的主题由MyTheme.js
导出,并且你想要使用Aphrodite,你可以在你自己的withStyles.js
文件中进行设置。
import ThemedStyleSheet from 'react-with-styles/lib/ThemedStyleSheet';
import aphroditeInterface from 'react-with-styles-interface-aphrodite';
import { css, withStyles } from 'react-with-styles';
import MyTheme from './MyTheme';
ThemedStyleSheet.registerTheme(MyTheme);
ThemedStyleSheet.registerInterface(aphroditeInterface);
export { css, withStyles, ThemedStyleSheet };
在这里传递react-with-styles
中的css
和withStyles
很方便,这样你无论在哪里使用它们,都能确保主题和接口已被注册。你也可以将其设置为添加到捆绑包顶部的初始化程序,然后直接在组件中使用react-with-styles
。
在你的组件中,从上面的withStyles.js
文件中,使用withStyles()
定义样式,使用css()
使用它们。
import React from 'react';
import PropTypes from 'prop-types';
import { css, withStyles } from './withStyles';
function MyComponent({ styles }) {
return (
<div>
<a
href="/somewhere"
{...css(styles.firstLink)}
>
A link to somewhere
</a>
{' '}
and
{' '}
<a
href="/somewhere-else"
{...css(styles.secondLink)}
>
a link to somewhere else
</a>
</div>
);
}
MyComponent.propTypes = {
styles: PropTypes.object.isRequired,
};
export default withStyles(({ color }) => ({
firstLink: {
color: color.primary,
},
secondLink: {
color: color.secondary,
},
}))(MyComponent);
ThemedStyleSheet
注册主题和接口。
ThemedStyleSheet.registerTheme(theme)
注册主题。theme
是一个对象,包含你希望在为组件设置样式时可用的属性。
import ThemedStyleSheet from 'react-with-styles/lib/ThemedStyleSheet';
ThemedStyleSheet.registerTheme({
color: {
primary: '#FF5A5F',
secondary: '#00A699',
},
});
ThemedStyleSheet.registerInterface(interface)
指示react-with-styles如何处理你的样式。
import ThemedStyleSheet from 'react-with-styles/lib/ThemedStyleSheet';
import aphroditeInterface from 'react-with-styles-interface-aphrodite';
ThemedStyleSheet.registerInterface(aphroditeInterface);
withStyles([ stylesThunk [, options ] ])
这是一个高阶函数,它返回一个用于包装React组件以使用主题添加样式的高阶组件。我们使用它来使主题样式更容易使用。
stylesThunk
将接收主题作为参数,它应该返回一个包含组件样式的对象。
被包装的组件将接收一个包含此组件的已处理样式的styles
prop和一个包含主题对象的theme
prop。大多数情况下,你只需要styles
prop。对theme
prop的依赖应该最小化。
import React from 'react';
import { css, withStyles } from './withStyles';
function MyComponent({ styles }) {
return (
<div {...css(styles.container)}>
Try to be a rainbow in someone's cloud.
</div>
);
}
export default withStyles(({ color, unit }) => ({
container: {
color: color.primary,
marginBottom: 2 * unit,
},
}))(MyComponent);
或者,作为装饰器
import React from 'react';
import { css, withStyles } from './withStyles';
@withStyles(({ color, unit }) => ({
container: {
color: color.primary,
marginBottom: 2 * unit,
},
}))
export default function MyComponent({ styles }) {
return (
<div {...css(styles.container)}>
Try to be a rainbow in someone's cloud.
</div>
);
}
pureComponent
(默认值:false
,React 15.3.0+)默认情况下,withStyles()
将创建一个扩展React.Component
的组件。如果你想应用React.PureComponent
提供的shouldComponentUpdate()
优化,可以将pureComponent
选项设置为true
。请注意,React.PureComponent
是在React 15.3.0中引入的,因此只有在你使用该版本或更高版本时,此方法才有效。
stylesPropName
(默认值:'styles'
)默认情况下,withStyles()
将styles
prop中的样式传递给被包装的组件,但是可以通过设置stylesPropName
选项来自定义此prop的名称。如果你已经有一个名为styles
的prop并且无法更改它,这将很有用。
import React from 'react';
import { css, withStyles } from './withStyles';
function MyComponent({ withStylesStyles }) {
return (
<div {...css(withStylesStyles.container)}>
Try to be a rainbow in someone's cloud.
</div>
);
}
export default withStyles(({ color, unit }) => ({
container: {
color: color.primary,
marginBottom: 2 * unit,
},
}), { stylesPropName: 'withStylesStyles' })(MyComponent);
themePropName
(默认值 'theme'
)同样,主题prop名称也可以通过设置themePropName
选项来自定义。
import React from 'react';
import { css, withStyles } from './withStyles';
function MyComponent({ styles, withStylesTheme }) {
return (
<div {...css(styles.container)}>
<Background color={withStylesTheme.color.primary}>
Try to be a rainbow in someone's cloud.
</Background>
</div>
);
}
export default withStyles(({ color, unit }) => ({
container: {
color: color.primary,
marginBottom: 2 * unit,
},
}), { themePropName: 'withStylesTheme' })(MyComponent);
flushBefore
(默认值:false
)某些组件依赖于挂载时组件树中之前的样式已准备好(例如尺寸计算)。一些接口异步地将样式添加到页面,这对这是个障碍。因此,我们提供了一个在渲染周期开始之前刷新缓冲样式的选项。接口需要定义这意味着什么。
css(...styles)
此函数接受由withStyles()
处理的样式、普通对象或这些内容的数组。它返回一个具有不透明结构的对象,必须将其展开到JSX元素中。
import React from 'react';
import { css, withStyles } from './withStyles';
function MyComponent({ bold, padding, styles }) {
return (
<div {...css(styles.container, { padding })}>
Try to be a rainbow in{' '}
<a
href="/somewhere"
{...css(styles.link, bold && styles.link_bold)}
>
someone's cloud
</a>
</div>
);
}
export default withStyles(({ color, unit }) => ({
container: {
color: color.primary,
marginBottom: 2 * unit,
},
link: {
color: color.secondary,
},
link_bold: {
fontWeight: 700,
},
}))(MyComponent);
className
和style
prop不能与css()
在相同的元素上使用。
Link
React Router的<Link/>
和<IndexLink/>
组件接受activeClassName='...'
和activeStyle={{...}}
作为prop。如前所述,css(...styles)
必须展开到JSX,因此直接传递styles.thing
甚至css(styles.thing)
将不起作用。为了模拟activeClassName
/activeStyles
,你可以使用React Router的withRouter()
高阶组件将router
作为prop传递给你的组件,并根据router.isActive(pathOrLoc, indexOnly)
切换样式。这是有效的,因为<Link />
将生成的className
从css(..styles)
传递到最终的叶子。
import React from 'react';
import { withRouter, Link } from 'react-router';
import { css, withStyles } from '../withStyles';
function Nav({ router, styles }) {
return (
<div {...css(styles.container)}>
<Link
to="/"
{...css(styles.link, router.isActive('/', true) && styles.link_bold)}
>
home
</Link>
<Link
to="/somewhere"
{...css(styles.link, router.isActive('/somewhere', true) && styles.link_bold)}
>
somewhere
</Link>
</div>
);
}
export default withRouter(withStyles(({ color, unit }) => ({
container: {
color: color.primary,
marginBottom: 2 * unit,
},
link: {
color: color.primary,
},
link_bold: {
fontWeight: 700,
}
}))(Nav));