Chuyển tên lớp vào các thành phần phản ứng


97

Tôi đang cố gắng chuyển một tên lớp cho một thành phần phản ứng để thay đổi kiểu của nó và dường như không thể hoạt động:

class Pill extends React.Component {

  render() {

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

}

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

Tôi đang cố gắng thay đổi kiểu dáng của viên thuốc bằng cách chuyển vào tên của lớp có kiểu dáng tương ứng. Tôi chưa quen với React nên có thể tôi đang làm điều này không đúng cách. Cảm ơn

Câu trả lời:


134

Trong React, khi bạn muốn truyền một biểu thức đã thông dịch, bạn phải mở một cặp dấu ngoặc nhọn. Thử:

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

Sử dụng gói npm của tên lớp

import classnames from 'classnames';

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

3
Tại sao nó tốt hơn: hiệu suất? khả năng đọc? khác ? Chuỗi chữ (ví dụ đầu tiên của bạn) là một phần của ES6, vì vậy nó là một tiêu chuẩn. Nó tạo ra ít mã hơn và tránh nhập khẩu. Nó cảm thấy tốt hơn cho tôi, nhưng giải pháp khác có thể có tranh luận.
Mose

2
Trong ví dụ trên, bạn hoàn toàn đúng, tốt hơn là sử dụng chuỗi ES6. Tôi muốn nói rằng tên lớp tốt hơn về mặt dễ đọc và KHÔ khi bạn phải xử lý các điều kiện, như trong các tên lớp readme cho thấy github.com/JedWatson/classnames#usage-with-reactjs .
gcedo

{} Dấu ngoặc nhọn, [] Dấu ngoặc, () Dấu ngoặc đơn - bạn không cần phải nói "dấu ngoặc nhọn" vì dấu ngoặc nhọn theo định nghĩa.
Rex the Strange

24

Chỉ để tham khảo, cho các thành phần không trạng thái:

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

Sẽ kết xuất:

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

Không nên thêm className prop vào một thành phần React sẽ truyền className đó vào phần tử container đầu tiên thay vì chuyển nó dưới dạng tên prop?
theSereneRebel

1
@theSereneRebel Không, nó không. Xem ví dụ tại đây: Codeandbox.io/s/clever-knuth-enyju
Mahdi

@theSereneRebel Cho dù đó là một điều tốt hay không là một chủ đề khác.
Mahdi

18

pill ${this.props.styleName} sẽ nhận được "viên thuốc không xác định" khi bạn không đặt đạo cụ

tôi thích

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

hoặc là

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

7

Đối với bất kỳ ai quan tâm, tôi đã gặp phải vấn đề tương tự khi sử dụng mô-đun cssmô-đun phản ứng css .

Hầu hết các thành phần đều có kiểu mô-đun css được liên kết và trong ví dụ này, Nút của tôi có tệp css riêng của nó, cũng như thành phần mẹ Promo . Nhưng tôi muốn chuyển một số kiểu bổ sung cho Nút từ Quảng cáo

Vì vậy, stylenút có thể trông như thế này:

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

Trong thành phần Nút ở trên, các kiểu Button.css xử lý các kiểu nút phổ biến. Trong ví dụ này, chỉ một .buttonlớp

Sau đó, trong thành phần của tôi, nơi tôi muốn sử dụng Nút và tôi cũng muốn sửa đổi những thứ như vị trí của nút, tôi có thể đặt các kiểu bổ sung vào Promo.cssvà chuyển qua làm chỗ dựa className. Trong ví dụ này một lần nữa được gọi là .buttonlớp. Tôi có thể gọi nó là bất cứ thứ gì, ví dụ promoButton.

Tất nhiên với mô-đun css, lớp này sẽ là .Promo__button___2MVMDtrong khi nút một sẽ giống như.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} );

Bản cập nhật năm 2018: Sử dụng propTypesdefaultProps để xử lý các trường hợp trong đó một thuộc tính có thể tồn tại hoặc có thể không tồn tại sẽ sạch hơn và được ưu tiên hơn.
BrianHVB

6

Như người khác đã nêu, hãy sử dụng một biểu thức được thông dịch với dấu ngoặc nhọn.

Nhưng đừng quên đặt mặc định.
Những người khác đã đề xuất sử dụng câu lệnh OR để đặt một chuỗi rỗng nếu undefined.

Nhưng sẽ tốt hơn nếu bạn khai báo Props.

Ví dụ đầy đủ:

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

Bạn có thể đạt được điều này bằng cách "nội suy" className được truyền từ thành phần mẹ sang thành phần con bằng cách sử dụng this.props.className. Ví dụ bên dưới:

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

Với React 16.6.3 và @Material UI 3.5.1, tôi đang sử dụng các mảng trong className như className={[classes.tableCell, classes.capitalize]}

Hãy thử một cái gì đó như sau trong trường hợp của bạn.

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

0

Với sự hỗ trợ của React cho nội suy chuỗi, bạn có thể làm như sau:

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


0

Trong Typecript, bạn cần đặt các loại HTMLAttributesReact.FunctionComponent.

Trong hầu hết các trường hợp, bạn sẽ cần mở rộng nó sang giao diện hoặc kiểu khác.

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;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.