如果你熟悉在組件中導入 CSS(例如 CSSModules),那么下面的寫法你一定不陌生:
import React from 'react' import styles from './styles.css' export default class Counter extends React.Component { state = { count: 0 } increment = () => this.setState({ count: this.state.count + 1 }) decrement = () => this.setState({ count: this.state.count - 1 }) render() { return ( <div className={styles.counter}> <p className={styles.paragraph}>{this.state.count}</p> <button className={styles.button} onClick={this.increment}> + </button> <button className={styles.button} onClick={this.decrement}> - </button> </div> ) } }
由于 Styled Component 是 HTML 元素和作用在元素上的樣式規(guī)則的組合, 我們可以這樣編寫Counter:
import React from 'react' import styled from 'styled-components' const StyledCounter = styled.div` /* ... */ ` const Paragraph = styled.p` /* ... */ ` const Button = styled.button` /* ... */ ` export default class Counter extends React.Component { state = { count: 0 } increment = () => this.setState({ count: this.state.count + 1 }) decrement = () => this.setState({ count: this.state.count - 1 }) render() { return ( <StyledCounter> <Paragraph>{this.state.count}</Paragraph> <Button onClick={this.increment}>+</Button> <Button onClick={this.decrement}>-</Button> </StyledCounter> ) } }
注意,我們在StyledCounter添加了"Styled"前綴,這樣組件Counter 和StyledCounter 不會明明沖突,而且可以在 React Developer Tools 和 Web Inspector 中輕松識別.
在 render 方法之外定義 styled component 很重要, 不然 styled component 會在每個渲染過程中重新創(chuàng)建. 這將阻止緩存生效并且大大降低了渲染速度,所以盡量避免這種情況.
推薦通過以下方式創(chuàng)建 styled components :
const StyledWrapper = styled.div` /* ... */ ` const Wrapper = ({ message }) => { return <StyledWrapper>{message}</StyledWrapper> }
而不是:
const Wrapper = ({ message }) => { // WARNING: 別這么干,會很慢!!! const StyledWrapper = styled.div` /* ... */ ` return <StyledWrapper>{message}</StyledWrapper> }
推薦閱讀:Talia Marcassa 寫了一篇很精彩的有關(guān)styled-components實際應用的文章,包含許多實用的見解以及與其它方案的比較Styled Components: To Use or Not to Use?
styled-component 所使用的預處理器stylis支持自動嵌套的 scss-like 語法,示例如下:
const Thing = styled.div` color: blue; `
偽元素和偽類無需進一步細化,而是自動附加到了組件:
const Thing = styled.button` color: blue; ::before { content: '????'; } :hover { color: red; } ` render( <Thing>Hello world!</Thing> )
對于更復雜的選擇器,可以使用與號(&)來指向主組件.以下是一些示例:
const Thing = styled.div.attrs({ tabIndex: 0 })` color: blue; &:hover { color: red; // <Thing> when hovered } & ~ & { background: tomato; // <Thing> as a sibling of <Thing>, but maybe not directly next to it } & + & { background: lime; // <Thing> next to <Thing> } &.something { background: orange; // <Thing> tagged with an additional CSS class ".something" } .something-else & { border: 1px solid; // <Thing> inside another element labeled ".something-else" } ` render( <React.Fragment> <Thing>Hello world!</Thing> <Thing>How ya doing?</Thing> <Thing className="something">The sun is shining...</Thing> <div>Pretty nice day today.</div> <Thing>Don't you think?</Thing> <div className="something-else"> <Thing>Splendid.</Thing> </div> </React.Fragment> )
如果只寫選擇器而不帶&,則指向組件的子節(jié)點.
const Thing = styled.div` color: blue; .something { border: 1px solid; // an element labeled ".something" inside <Thing> display: block; } ` render( <Thing> <label htmlFor="foo-button" className="something">Mystery button</label> <button id="foo-button">What do I do?</button> </Thing> )
最后,&可以用于增加組件的差異性;在處理混用 styled-components 和純 CSS 導致的樣式?jīng)_突時這將會非常有用:
const Thing = styled.div` && { color: blue; } ` const GlobalStyle = createGlobalStyle` div${Thing} { color: red; } ` render( <React.Fragment> <GlobalStyle /> <Thing> I'm blue, da ba dee da ba daa </Thing> </React.Fragment> )
更多建議: