styled-components Coming from CSS

2020-07-24 14:02 更新

styled-components 如何在組件中工作?

如果你熟悉在組件中導入 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 Components

在 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>
)


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號