Передавання імен класів для реагування компонентів


97

Я намагаюся передати ім'я класу компоненту response, щоб змінити його стиль, і, здається, не працює:

class Pill extends React.Component {

  render() {

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

}

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

Я намагаюся змінити стиль таблетки, передавши назву класу, який має відповідний стиль. Я новачок у React, тому, можливо, я роблю це не так. Дякую

Відповіді:


134

У React, коли ви хочете передати інтерпретований вираз, ви повинні відкрити пару фігурних дужок. Спробуйте:

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

Використання пакету назв класів npm

import classnames from 'classnames';

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

3
Чому це краще: продуктивність? читабельність? інші? Літеральні рядки (ваш перший приклад) є частиною ES6, тому це стандарт. Це робить менше коду і уникає імпорту. Він відчуває себе краще для мене, але інше рішення може мати аргументи.
Mose

2
У наведеному вище прикладі ви абсолютно праві, краще використовувати рядки ES6. Я б сказав, що імена класів кращі з точки зору читабельності та СУХОСТІ, коли доводиться мати справу з умовними умовами, як у іменах класів readme показує github.com/JedWatson/classnames#usage-with-reactjs .
gcedo 02.03.17

{} Фігурні дужки, [] Дужки, () Дужки - вам не потрібно говорити "фігурні дужки", оскільки дужки фігурні за визначенням.
Рекс Дивний

24

Тільки для довідки, для компонентів без громадянства:

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

Чи не слід додавання властивості className до компонента React передати це className першому елементу-контейнеру, замість того, щоб передавати його як властивість імені?
theSereneRebel

1
@theSereneRebel Ні, ні. Дивіться приклад тут: codesandbox.io/s/clever-knuth-enyju
Махді

@theSereneRebel Чи добре це чи ні, - це вже інша тема.
Махді,

18

pill ${this.props.styleName} отримає "таблетка невизначена", якщо ви не встановите реквізит

я віддаю перевагу

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

або

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

7

Для всіх, хто цікавиться, я зіткнувся з цією ж проблемою, використовуючи css-модулі та реагуючи на css-модулі .

Більшість компонентів мають асоційований стиль модуля css, і в цьому прикладі моя кнопка має власний файл css, як і батьківський компонент Promo . Але я хочу передати додаткові стилі Button від Promo

Отже, 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клас

Потім у своєму компоненті, де я хочу використовувати кнопку , і я також хочу змінити такі речі, як положення кнопки, я можу встановити додаткові стилі Promo.cssта передати їх як classNameпідставку. У цьому прикладі знову називається .buttonclass. Я міг би це назвати як завгодно, наприклад promoButton.

Звичайно, з модулями css цей клас буде, .Promo__button___2MVMDтоді як кнопковий - щось на зразок.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 Оновлення Використання propTypes і defaultProps обробляти випадки , коли властивість може або не може існувати чистіше, і кращий.
BrianHVB

6

Як зазначали інші, використовуйте інтерпретований вираз із фігурними дужками.

Але не забудьте встановити значення за замовчуванням.
Інші пропонують використовувати оператор OR для встановлення порожнього рядка if 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 like 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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.