Bileşenlere tepki vermek için sınıf adlarının aktarılması


98

Tarzını değiştirmek için bir sınıf adını bir tepki bileşenine geçirmeye çalışıyorum ve çalışmıyor gibi görünüyorum:

class Pill extends React.Component {

  render() {

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

}

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

İlgili stile sahip sınıfın adını geçerek hapın stilini değiştirmeye çalışıyorum. React'te yeniyim, bu yüzden belki de bunu doğru şekilde yapmıyorum. Teşekkürler

Yanıtlar:


134

React'te, yorumlanmış bir ifadeyi geçmek istediğinizde, bir çift kaşlı ayraç açmanız gerekir. Deneyin:

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

Kullanılması classnames npm paketi

import classnames from 'classnames';

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

3
Neden daha iyi: performans? okunabilirlik? diğerleri? Değişmez dizeler (ilk örneğiniz) ES6'nın bir parçasıdır, bu yüzden bir standarttır. Daha az kod üretir ve içe aktarmayı önler. Benim için daha iyi hissettiriyor , ancak diğer çözümün argümanları olabilir.
Mose

2
Yukarıdaki örnekte kesinlikle haklısınız, ES6 dizelerini kullanmak daha iyidir. Sınıf adlarının , koşullularla uğraşmanız gerektiğinde okunabilirlik ve KURU açısından daha iyi olduğunu söyleyebilirim, beni oku sınıf adlarında olduğu gibi github.com/JedWatson/classnames#usage-with-reactjs .
gcedo 02

{} Küme parantezleri, [] Parantezler, () Parantezler - "kaşlı parantez" demenize gerek yoktur çünkü kaşlı ayraçlar tanım gereği küme parantezidir.
Rex the Strange

25

Yalnızca referans için, durum bilgisiz bileşenler için:

// 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>

Oluşturacak:

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

Bir React bileşenine className prop eklemek, className'i bir name prop olarak iletmek yerine ilk konteyner elemanına geçirmemeli mi?
theSereneRebel

1
@theSereneRebel Hayır, öyle değil. Burada bir örnek görün: codesandbox.io/s/clever-knuth-enyju
Mahdi

@theSereneRebel Bunun iyi bir şey olup olmadığı farklı bir konu.
Mehdi

18

pill ${this.props.styleName} sahne ayarını yapmadığınızda "tanımlanmamış hap" alacak

tercih ederim

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

veya

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

7

İlgilenen herkes için, css modüllerini kullanırken ve css modüllerine tepki verirken aynı sorunu yaşadım .

Çoğu bileşenin ilişkili bir css modülü stili vardır ve bu örnekte , Promo ana bileşeninde olduğu gibi Button'ım kendi css dosyasına sahiptir . Ama bazı ek stiller geçmek istiyorum Düğme gelen Promo

Böylece stylemümkün Düğme şuna benzer:

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

Yukarıdaki Button bileşeninde Button.css stilleri ortak düğme stillerini ele alır. Bu örnekte sadece bir .buttonsınıf

Ardından, Düğmeyi kullanmak istediğim bileşenimde ve ayrıca düğmenin konumu gibi şeyleri değiştirmek istiyorum, ek stiller ayarlayabilir Promo.cssve classNamedestek olarak geçebilirim . Bu örnekte yine .buttonsınıf denir . Örneğin buna herhangi bir şey diyebilirdim promoButton.

Tabii ki css modülleri ile bu sınıf olacaktır, .Promo__button___2MVMDoysa birinci düğme gibi bir şey olacaktır..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 güncellemesi: Bir özelliğin var olabileceği veya olmayabileceği durumları ele almak için propTypes ve defaultProps kullanmak daha temiz ve tercih edilir.
BrianHVB

6

Diğerlerinin de belirttiği gibi, kaşlı ayraçlar içeren yorumlanmış bir ifade kullanın.

Ancak bir varsayılan ayarlamayı unutmayın.
Diğerleri, eğer boş bir dizge ayarlamak için bir VEYA ifadesi kullanmayı önerdi undefined.

Ancak, Dikmelerinizi ilan etmeniz daha da iyi olur.

Tam örnek:

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

Bunu, ana bileşenden alt bileşene iletilen className'i kullanarak "enterpolasyon yaparak" elde edebilirsiniz this.props.className. Aşağıdaki örnek:

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 ve @Material UI 3.5.1 ile, className'deki gibi dizileri kullanıyorum className={[classes.tableCell, classes.capitalize]}

Sizin durumunuzda aşağıdakine benzer bir şey deneyin.

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

0

React'in dize enterpolasyonu desteği ile aşağıdakileri yapabilirsiniz:

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


0

Typescript'te HTMLAttributesve türlerini belirlemeniz gerekir React.FunctionComponent.

Çoğu durumda, onu başka bir arayüz veya türe genişletmeniz gerekecektir.

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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.