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
プロパティと、テーマオブジェクトを含む theme
プロパティを受け取ります。ほとんどの場合、styles
プロパティのみが必要になります。 theme
プロパティへの依存は最小限に抑える必要があります。
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
プロパティのラップされたコンポーネントにスタイルを渡しますが、このプロパティの名前は stylesPropName
オプションを設定することでカスタマイズできます。これは、すでに styles
というプロパティがあり、変更できない場合に役立ちます。
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'
)同様に、テーマプロパティ名も 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
プロパティは、css()
と同じ要素で使用しないでください。
Link
を使用React Router の <Link/>
および <IndexLink/>
コンポーネントは、activeClassName='...'
および activeStyle={{...}}
をプロパティとして受け入れます。前述のように、css(...styles)
は JSX にスプレッドする必要があるため、styles.thing
や css(styles.thing)
を直接渡しても機能しません。 activeClassName
/activeStyles
を模倣するには、React Router の withRouter()
高階コンポーネントを使用して router
をプロパティとしてコンポーネントに渡し、router.isActive(pathOrLoc, indexOnly)
に基づいてスタイルを切り替えることができます。これは、<Link />
が css(..styles)
から生成された className
を最終的なリーフに渡すためです。
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));