Przekazywanie nazw klas do reagowania komponentów


97

Próbuję przekazać nazwę klasy do komponentu reagowania, aby zmienić jego styl i wydaje się, że nie działa:

class Pill extends React.Component {

  render() {

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

}

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

Próbuję zmienić styl pigułki, podając nazwę klasy, która ma odpowiedni styl. Jestem nowy w React, więc może nie robię tego we właściwy sposób. Dzięki

Odpowiedzi:


134

W Reakcie, gdy chcesz przekazać interpretowane wyrażenie, musisz otworzyć parę nawiasów klamrowych. Próbować:

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

Korzystanie z pakietu nazw klas npm

import classnames from 'classnames';

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

3
Dlaczego jest lepiej: wydajność? czytelność? inni? Literalne łańcuchy (Twój pierwszy przykład) są częścią ES6, więc jest to standard. Tworzy mniej kodu i pozwala uniknąć importu. To czuje się lepiej dla mnie, ale inne rozwiązanie może mieć argumenty.
Mose

2
W powyższym przykładzie masz całkowitą rację, lepiej jest używać ciągów ES6. Powiedziałbym, że nazwy klas są lepsze pod względem czytelności i DRY, gdy masz do czynienia z warunkami warunkowymi, tak jak w pliku readme nazw klas pokazuje github.com/JedWatson/classnames#usage-with-reactjs .
gcedo

{} Nawiasy, [] Nawiasy, () Nawiasy - nie musisz mówić „nawiasy klamrowe”, ponieważ nawiasy klamrowe są z definicji.
Rex the Strange

24

Tylko w celach informacyjnych, dla komponentów bezstanowych:

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

Wyrenderuje:

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

Czy dodanie właściwości className do komponentu React nie powinno przekazywać tej className do pierwszego elementu kontenera zamiast przekazywać ją jako właściwość nazwy?
theSereneRebel

1
@theSereneRebel Nie, tak nie jest. Zobacz przykład tutaj : codeandbox.io/s/clever-knuth-enyju
Mahdi

@theSereneRebel To, czy to dobrze, czy nie, to inny temat.
Mahdi

18

pill ${this.props.styleName} dostanie „pigułka niezdefiniowana”, jeśli nie ustawisz właściwości

wolę

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

lub

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

7

Dla wszystkich zainteresowanych napotkałem ten sam problem podczas używania modułów css i reagowania modułów css .

Większość komponentów ma powiązany styl modułu css, aw tym przykładzie my Button ma własny plik css, podobnie jak komponent nadrzędny Promo . Ale chcę przekazać Button z Promo kilka dodatkowych stylów

Więc style sprawny przycisk wygląda następująco:

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

W powyższym komponencie Button style Button.css obsługują typowe style przycisków. W tym przykładzie tylko plik.button klasa

Następnie w moim komponencie, w którym chcę użyć przycisku , a także chcę zmodyfikować takie rzeczy, jak położenie przycisku, mogę ustawić dodatkowe style Promo.cssi przejść jako classNamerekwizyt. W tym przykładzie ponownie nazwano .buttonclass. Mógłbym to nazwać cokolwiek nppromoButton .

Oczywiście z modułami css ta klasa będzie, .Promo__button___2MVMDnatomiast przycisk pierwszy będzie czymś podobnym.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} );

Aktualizacja 2018: używanie propTypes i defaultProps do obsługi przypadków, w których właściwość może istnieć lub nie, jest bardziej przejrzyste i preferowane.
BrianHVB

6

Jak powiedzieli inni, użyj wyrażenia interpretowanego z nawiasami klamrowymi.

Ale nie zapomnij ustawić wartości domyślnej.
Inni sugerowali użycie instrukcji OR, aby ustawić pusty ciąg znaków, jeśli undefined.

Ale byłoby jeszcze lepiej zadeklarować swoje rekwizyty.

Pełny przykład:

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

Można to osiągnąć przez „interpolację” nazwy klasy przekazanej z komponentu nadrzędnego do komponentu potomnego za pomocą this.props.className. Przykład poniżej:

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

W React 16.6.3 i @Material UI 3.5.1 używam tablic w className, takich jak className={[classes.tableCell, classes.capitalize]}

W swoim przypadku spróbuj czegoś podobnego do następującego.

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

0

Dzięki wsparciu Reacta dla interpolacji ciągów możesz wykonać następujące czynności:

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


0

W Typescript musisz ustawić typy HTMLAttributesi React.FunctionComponent.

W większości przypadków będziesz musiał rozszerzyć go na inny interfejs lub typ.

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;
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.