コンポーネントを反応させるためにクラス名を渡す


92

クラス名をreactコンポーネントに渡してスタイルを変更しようとしていますが、うまくいかないようです:

class Pill extends React.Component {

  render() {

    return (
      <button className="pill {this.props.styleName}">{this.props.children}</button>
    );
  }

}

<Pill styleName="skill">Business</Pill>

それぞれのスタイルを持つクラスの名前を渡すことで、ピルのスタイルを変更しようとしています。私はReactを初めて使用するので、これを正しい方法で行っていない可能性があります。ありがとう

回答:


130

Reactでは、解釈された式を渡したい場合は、中括弧のペアを開く必要があります。試してください:

render () {
  return (
    <button className={`pill ${ this.props.styleName }`}>
      {this.props.children}
    </button>
  );
}

classnames npmパッケージの使用

import classnames from 'classnames';

render() {
  return (
    <button className={classnames('pill', this.props.styleName)}>
      {this.props.children}
    </button>
  );
}

3
なぜそれが良いのですか?パフォーマンス?読みやすさ?その他?リテラル文字列(最初の例)はES6の一部なので、標準です。コードが減り、インポートが回避されます。それ私に良い感じですが、他の解決策には議論があるかもしれません。
Mose

2
上記の例では完全に正しいので、ES6文字列を使用することをお勧めします。classnames readmeがgithub.com/JedWatson/classnames#usage-with-reactjsを表示するように、条件を処理する必要がある場合、読みやすさとDRYの点でclassnamesの方が優れていると思います。
gcedo 2017年

{}中かっこ、[]かっこ、()かっこ-中かっこは定義上中かっこなので、「中かっこ」と言う必要はありません。
Rex the Strange

21

参考までに、ステートレスコンポーネントの場合:

// ParentComponent.js
import React from 'react';
import { ChildComponent } from '../child/ChildComponent';

export const ParentComponent = () =>
  <div className="parent-component">
    <ChildComponent className="parent-component__child">
      ...
    </ChildComponent>
  </div>

// ChildComponent.js
import React from 'react';

export const ChildComponent = ({ className, children }) =>
  <div className={`some-css-className ${className}`}>
    {children}
  </div>

レンダリングします:

<div class="parent-component">
  <div class="some-css-className parent-component__child">
    ...
  </div>
</div>

ReactコンポーネントにclassNameプロップを追加して、名前プロップとして渡すのではなく、そのclassNameを最初のコンテナー要素に渡すべきではありませんか?
theSereneRebel

@theSereneRebelいいえ、ありません。こちらの例をご覧ください:codesandbox.io/s/clever-knuth-enyju
Mahdi

@theSereneRebelそれが良いことかどうかは別のトピックです。
Mahdi

17

pill ${this.props.styleName} 小道具を設定しないと「ピルが未定義」になります

私は好む

className={ "pill " + ( this.props.styleName || "") }

または

className={ "pill " + ( this.props.styleName ? this.props.styleName : "") }

7

興味のある方のために、私はcssモジュールを使用してcssモジュール反応させたときに同じ問題に遭遇しました。

ほとんどのコンポーネントにはcssモジュールスタイルが関連付けられています。この例では、Promo親コンポーネントと同様に、私のボタンには独自のcssファイルがあります。しかし、私はにいくつかの追加のスタイルを渡したいボタンからプロモ

したがって、可能styleなボタンは次のようになります。

Button.js

import React, { Component } from 'react'
import CSSModules from 'react-css-modules'
import styles from './Button.css'

class Button extends Component {

  render() {

    let button = null,
        className = ''

    if(this.props.className !== undefined){
        className = this.props.className
    }

    button = (
      <button className={className} styleName='button'>
        {this.props.children}
      </button>
    )

    return (
        button
    );
  }
};

export default CSSModules(Button, styles, {allowMultiple: true} )

上記のButtonコンポーネントでは、Button.cssスタイルが一般的なボタンスタイルを処理します。この例では、.buttonクラス

次に、Buttonを使用するコンポーネントで、ボタンの位置なども変更したい場合は、追加のスタイルを設定Promo.cssして、className小道具として通過させることができます。この例では、再び.buttonクラスを呼び出しました。私はそれを何とでも呼べたでしょうpromoButton

もちろんcssモジュールの場合、このクラスは.Promo__button___2MVMDボタン1のようになりますが.Button__button___3972N

Promo.js

import React, { Component } from 'react';
import CSSModules from 'react-css-modules';
import styles from './Promo.css';

import Button from './Button/Button'

class Promo extends Component {

  render() {

    return (
        <div styleName='promo' >
          <h1>Testing the button</h1>
          <Button className={styles.button} >
            <span>Hello button</span>
          </Button>
        </div>
      </Block>
    );
  }
};

export default CSSModules(Promo, styles, {allowMultiple: true} );

2018年の更新:propTypesdefaultPropsを使用して、プロパティが存在する場合と存在しない場合のケースを処理することは、よりクリーンで好ましい方法です。
BrianHVB

6

他の人が述べたように、中括弧で解釈された式を使用してください。

ただし、デフォルトを設定することを忘れないでください。
他の人は、ORステートメントを使用して空の文字列を設定することを提案していますundefined

しかし、あなたの小道具を宣言することはさらに良いでしょう。

完全な例:

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class Pill extends Component {

  render() {

    return (
      <button className={`pill ${ this.props.className }`}>{this.props.children}</button>
    );
  }

}

Pill.propTypes = {
  className: PropTypes.string,
};

Pill.defaultProps = {
  className: '',
};

4

これは、を使用して親コンポーネントから子コンポーネントに渡されたclassNameを「補間」することで実現できますthis.props.className。以下の例:

export default class ParentComponent extends React.Component {
  render(){
    return <ChildComponent className="your-modifier-class" />
  }
}

export default class ChildComponent extends React.Component {
  render(){
    return <div className={"original-class " + this.props.className}></div>
  }
}

1

React 16.6.3と@Material UI 3.5.1では、classNameで配列を使用しています className={[classes.tableCell, classes.capitalize]}

あなたの場合、次のようなことを試してください。

class Pill extends React.Component {
    render() {
        return (
           <button className={['pill', this.props.styleName]}>{this.props.children}</button>
        );
    }
}

0

Reactによる文字列補間のサポートにより、次のことが可能になります。

class Pill extends React.Component {
    render() {
       return (
          <button className={`pill ${this.props.styleName}`}>{this.props.children}</button>
       );
    }
}


0

Typescriptでは、HTMLAttributesおよびのタイプを設定する必要がありReact.FunctionComponentます。

ほとんどの場合、それを別のインターフェースまたはタイプに拡張する必要があります。

const List: React.FunctionComponent<ListProps &
  React.HTMLAttributes<HTMLDivElement>> = (
  props: ListProps & React.HTMLAttributes<HTMLDivElement>
) => {
  return (
    <div className={props.className}>
      <img className="mr-3" src={props.icon} alt="" />
      {props.context}
    </div>
  );
};

interface ListProps {
  context: string;
  icon: string;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.