為您的 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
在這裡很方便,這樣您就可以確保每次使用它們時都已註冊主題和介面。您也可以將其設定為初始化程式,並將其新增到您的 bundle 頂部,然後直接在您的組件中使用 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'
)同樣地,也可以透過設定 themePropName
選項來自訂主題 prop 的名稱。
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);
不得在與 css()
相同的元素上使用 className
和 style
prop。
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 />
會將從 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));