6

作曲について質問があります。誰かが私を助けてくれることを願っています。私はreact-css-modulesSass を使用していますが、基本的な最下位レベルのコンポーネントの 1 つを構成するための最良の方法を知りたいです。

コンポーネントは次のとおりです。

import React, {PropTypes} from 'react'
import cssModules from 'react-css-modules'
import styles from './style.sass'

const Button = ({children = 'Submit', ...props}) => {
  const align = props.align ? `-${props.align}` : ''
  const type = props.type ? `-${props.type}` : ''
  const styleName = `button${type}${align}`

  return (
    <button onClick={props.onClick} {...props} styleName={styleName}>
      {children}
    </button>
  )
}

Button.propTypes = {
  align: PropTypes.string,
  onClick: PropTypes.func.isRequired,
  type: PropTypes.string,
}

export default cssModules(Button, styles)

これまでのスタイルシートは次のとおりです。

@import "~components/styles/variables"

.button
  color: $button-default
  background-color: transparent
  font-family: $font-family
  font-size: $default-font-size
  font-weight: $font-regular
  line-height: $default-button-height
  margin: 0 $pad 0 0
  outline: none
  padding: 0 $pad*2

.left
  float: left

.right
  float: right

.primary
  color: $background-interaction
  background-color: $button-default

.button-left
  composes: button, left

.button-right
  composes: button, right

.button-primary
  composes: button, primary

.button-primary-left
  composes: button, primary, left

.button-primary-right
  composes: button, primary, right

今のところ、かなり痛いです。追加するすべての構成可能な props は、提供する必要がある構成されたクラスの数を指数関数的に増加させます。現在、 と を構成できますaligntypeどちらも null になる可能性があるため、可能な組み合わせは 6 つあります。つまり、 base に加えて 5 つの合成クラスを作成する必要があります.button。もう 1 つだけ props を追加した場合、たとえば boolean だけを追加した場合bold、新しい合成クラス名を大量に追加する必要があります.button-bold, .button-left-bold, .button-right-bold, .button-primary-bold, .button-primary-left-bold, .button-primary-right-bold

要素に適用する複数のモジュールを指定できるようreact-css-modulesに設定を有効にするだけでよいことはわかっていますが、それはベスト プラクティスに反していると理解しています。ここで何かが欠けているようallowMultipleに感じます。私たちは何を間違っていますか?

4

2 に答える 2

7

この例にはさまざまな懸念があり、それが「要素ごとに 1 つのクラス」という規則に適合しない理由だと思います。要素ごとに 1 つのクラスのルールを適用する理由の 1 つは、実際に要素に触れずに、要素の状態の外観を簡単に変更できるようにするためです。(基本的にCSS自体の約束、やっと実現。) 要素に複数のクラスがある場合、要素を変更せずに外観を制御することは困難です。これは、(セマンティックではなく) 外観クラスを使用する場合に特に当てはまります。

「button-primary-left-bold」のようなクラスには意味的な意味 (「button-primary」) がありますが、レイアウトの意味 (「左」) とテキストの外観の意味 (「太字」) もあります。Button コンポーネントには、おそらく独自のレイアウトを制御するビジネスはありません。React コンポーネントも作成できることを忘れないでください。したがって、次のようなものを使用できます。

<Left><Button type="primary">Click Me!</Button></Left>

これで、Button コンポーネントの CSS モジュールは、ボタンの種類だけを気にすることができます。また、Button コンポーネントは、float ベースのレイアウトだけでなく、任意のレイアウトでどこでも使用できます。

さらに良いことに、float をよりセマンティックなコンポーネントにプッシュすることもできます。おそらく次のようなものです:

<ButtonBar>
  <Button>Cancel</Button>
  <Button type="primary">Save</Button>
</ButtonBar>

ButtonBar は、レイアウトを行う独自の CSS モジュールを持つことができます。そして後で、そのぎこちないフロート レイアウトをおしゃれなフレックスボックス レイアウトに交換できます。:-)

あなたの「太字」修飾子の例は、確かに Button コンポーネント内にはありません。なぜ太字なのかを考えてから、そのためのコンポーネントまたはセマンティック プロパティを作成することをお勧めします。それ以外の場合、デザインでこれらの「ボールド」ボタンを「イタリック グリーン」ボタンに変更する必要がある場合は、一連の要素を変更する必要があります。

これを行うと (セマンティック コンポーネントのビジュアル/レイアウト クラスを交換し、コンポーネントと CSS モジュールを分割する)、「指数関数的な増加」が少なくなります。実際に複数のセマンティック プロパティを組み合わせる必要がある状況に陥った場合でも、それらの状態を詳細に説明することには何らかの価値があります。良い例は「一次無効化」です。これは、いくつかの理由から、「プライマリ無効」よりも優れています。まず、CSS モジュールを見て、リストされている明示的な状態を確認するのは簡単です。第 2 に、それらのクラスの用途や関係があいまいではありません。「プライマリ無効」は実際にこれらのクラスの有効な使用法ですか? それは、誰かがドキュメントを使用している場合にのみ知ることができます。「無効」クラスは、「プライマリ」クラスの何かをオーバーライドする可能性があります。つまり、暗黙的な順序の依存関係があります。これらのクラス間の関係は明らかではないため、将来の善意の編集によって物事が壊れやすくなります。よくあることですが、いくつかのキーストロークを節約するために暗黙的なものを選択すると、微妙なエラーが発生する可能性があります。その少しのキーストローク税を支払うことで物事がロックされ、何が機能し、何が機能しないかが明確になります.

いくつかのキーストロークを節約するためのもう 1 つの小さなポイント: "button-" プレフィックスを付ける理由は実際にはありません。それがまさに CSS モジュールの目的です。代わりにこれを行います:

.normal
  color: $button-default
  background-color: transparent
  font-family: $font-family
  font-size: $default-font-size
  font-weight: $font-regular
  line-height: $default-button-height
  margin: 0 $pad 0 0
  outline: none
  padding: 0 $pad*2

.primary
  composes: normal
  color: $background-interaction
  background-color: $button-default

ファイル名自体は基本的に「ボタン」プレフィックスです。

于 2016-01-18T06:49:29.670 に答える
2

この場合、作成から離れて、クラスをネストすると思います。これが私の提案です(私のjsxが少しずれている場合はご容赦ください):

import React, {PropTypes} from 'react'
import cssModules from 'react-css-modules'
import styles from './style.sass'

const Button = ({children = 'Submit', ...props}) => {
  const align = props.align ? `${props.align}` : ''
  const type = props.type ? `${props.type}` : ''
  const styleName = `button ${type} ${align}`

  return (
    <button onClick={props.onClick} {...props} styleName={styleName}>
      {children}
    </button>
  )
}

Button.propTypes = {
  align: PropTypes.string,
  onClick: PropTypes.func.isRequired,
  type: PropTypes.string,
}

export default cssModules(Button, styles)

そしてSASS:

@import "~components/styles/variables"

.button
  color: $button-default
  background-color: transparent
  font-family: $font-family
  font-size: $default-font-size
  font-weight: $font-regular
  line-height: $default-button-height
  margin: 0 $pad 0 0
  outline: none
  padding: 0 $pad*2

  &.left
    float: left

  &.right
    float: right

  &.primary
    color: $background-interaction
    background-color: $button-default

"left" と "primary" がアプリ内の他のクラス名と競合する可能性があることを十分に認識してください。したがって、もう少し適切な (より範囲の広い) 名前を考え出すことは悪い考えではないかもしれません。

于 2015-12-17T00:28:01.453 に答える