React Js áp dụng có điều kiện các thuộc tính lớp


333

Tôi muốn hiển thị có điều kiện và ẩn nhóm nút này tùy thuộc vào nội dung được truyền từ thành phần chính trông như thế này:

<TopicNav showBulkActions={this.__hasMultipleSelected} />

....

__hasMultipleSelected: function() {
  return false; //return true or false depending on data
}

....

var TopicNav = React.createClass({
render: function() {
return (
    <div className="row">
        <div className="col-lg-6">
            <div className="btn-group pull-right {this.props.showBulkActions ? 'show' : 'hidden'}">
                <button type="button" className="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
                  Bulk Actions <span className="caret"></span>
                </button>
                <ul className="dropdown-menu" role="menu">
                  <li><a href="#">Merge into New Session</a></li>
                  <li><a href="#">Add to Existing Session</a></li>
                  <li className="divider"></li>
                  <li><a href="#">Delete</a></li>
                </ul>
            </div>
        </div>
    </div>
    );
  }
});

Tuy nhiên, không có gì xảy ra với {this.props.showBulkActions? 'hiển thị': 'ẩn'}. Tôi có làm gì sai ở đây không?


Bạn cũng có thể xem xét phản ứng-bootstrap , vì điều này trừu tượng hóa một số nội dung của lớp thành các thuộc tính thành phần, làm cho những gì bạn đang cố gắng thực hiện dễ dàng hơn một chút.
Dancrumb

Câu trả lời:


587

Các dấu ngoặc nhọn nằm trong chuỗi, vì vậy nó được đánh giá là chuỗi. Họ cần phải ở bên ngoài, vì vậy điều này sẽ hoạt động:

<div className={"btn-group pull-right " + (this.props.showBulkActions ? 'show' : 'hidden')}>

Lưu ý không gian sau khi "kéo sang phải". Bạn không muốn vô tình cung cấp lớp "pull-Rightshow" thay vì "pull-right show". Ngoài ra các dấu ngoặc cần phải ở đó.


3
Cảm ơn! Tôi đã phải sửa đổi nó một chút bởi vì một số lý do, nó đã không xuất hiện đúng theo nhóm btn. Chỉ hiển thị hoặc ẩn.
apexdodge

Điều này đặc biệt hữu ích trong một số trường hợp classnamescó thể không phù hợp. Nếu bạn đang ở trong renderchức năng của mình và bạn có một map, bạn có thể chỉ biết liệu bạn có muốn thêm một lớp tại thời điểm bạn kết xuất nó hay không, vì vậy câu trả lời này khá hữu ích cho việc đó.
Dave Cooper

thay thế tuyệt vời thay vì có một loạt các mẫu có điều kiện trong kết xuất hoặc trả về của bạn
devonj

@apexdodge bạn phải làm gì. Tôi có cùng một vấn đề.
RamY

1
@RamY Một cách là đặt tất cả các lớp bên trong điều kiện this.props.showBulkActions ? 'btn-group pull-right show' : 'btn-group pull-right hidden'). Không thanh lịch nhưng nó hoạt động.
Ian

87

Như những người khác đã nhận xét, tiện ích tên lớp là cách tiếp cận hiện được đề xuất để xử lý các tên lớp CSS có điều kiện trong ReactJs.

Trong trường hợp của bạn, giải pháp sẽ như sau:

var btnGroupClasses = classNames(
  'btn-group',
  'pull-right',
  {
    'show': this.props.showBulkActions,
    'hidden': !this.props.showBulkActions
  }
);

...

<div className={btnGroupClasses}>...</div>

Là một lưu ý phụ, tôi sẽ đề nghị bạn cố gắng tránh sử dụng cả hai showhiddencác lớp, để mã có thể đơn giản hơn. Nhiều khả năng bạn không cần phải thiết lập một lớp cho một cái gì đó được hiển thị theo mặc định.


11
Bạn có thể giải thích về tiện ích classNames là "cách tiếp cận hiện được đề xuất" không? Điều đó có được ghi lại trong một số tài liệu thực hành tốt nhất được đánh giá cao ở đâu đó không? Hay chỉ là sắp xếp những lời truyền miệng xung quanh React và classNamesvào lúc này?
Alexander Nied

6
@ kèm theo Tại thời điểm viết, nó được đề xuất trong tài liệu React chính thức: web.archive.org/web/20160602124910/http://facebook.github.io:80/
Diego V

3
Nó vẫn được đề cập trong tài liệu mới nhất : " Nếu bạn thường thấy mình viết mã như thế này, gói tên lớp có thể đơn giản hóa nó. "
Franklin Yu

66

Nếu bạn đang sử dụng bộ chuyển mã (như Babel hoặc Traceur), bạn có thể sử dụng " chuỗi mẫu " ES6 mới .

Đây là câu trả lời của @ spitfire109, được sửa đổi cho phù hợp:

<div className={`btn-group pull-right ${this.props.showBulkActions ? 'shown' : 'hidden'}`}>

Cách tiếp cận này cho phép bạn thực hiện những việc gọn gàng như thế, hiển thị s-is-shownhoặc s-is-hidden:

<div className={`s-${this.props.showBulkActions ? 'is-shown' : 'is-hidden'}`}>

20
Hãy cẩn thận với cách tiếp cận thứ hai, đặc biệt là trong các cơ sở mã lớn, vì nó làm cho các chuỗi lớp ít bị greppable. Ví dụ: nếu ai đó tìm kiếm s-is-shownhoặc s-is-hiddentrong cơ sở mã, họ sẽ không tìm thấy mã này.
đánh dấu

15

Bạn có thể sử dụng ở đây Chuỗi ký tự

const Angle = ({show}) => {

   const angle = `fa ${show ? 'fa-angle-down' : 'fa-angle-right'}`;

   return <i className={angle} />
}

9

Mong đợi câu trả lời hay của @ spitfire109, người ta có thể làm một cái gì đó như thế này:

rootClassNames() {
  let names = ['my-default-class'];
  if (this.props.disabled) names.push('text-muted', 'other-class');

  return names.join(' ');
}

và sau đó trong chức năng kết xuất:

<div className={this.rootClassNames()}></div>

giữ jsx ngắn


8

Hoặc sử dụng tên lớp npm . Nó rất dễ dàng và hữu ích đặc biệt là để xây dựng danh sách các lớp


8

Trong trường hợp bạn sẽ chỉ cần một tên lớp tùy chọn:

<div className={"btn-group pull-right " + (this.props.showBulkActions ? "show" : "")}>

1
Điều này sẽ nối falselớp khi điều kiện không thành công.
RA.

3
không, nó không
madhu131313


5

2019:

React là hồ rất nhiều tiện ích. Nhưng bạn không cần bất kỳ npmgói cho điều đó. chỉ cần tạo một nơi nào đó hàm classnamesvà gọi nó khi bạn cần;

function classnames(obj){
  return Object.entries(obj).filter( e => e[1] ).map( e=>e[0] ).join(' ');
}

hoặc là

function classnames(obj){
 return Object.entries(obj).map( ([k,v]) => v?k:'' ).join(' ');
}

thí dụ

  stateClass= {
    foo:true,
    bar:false,
    pony:2
  }
  classnames(stateClass) // return 'foo pony'

 <div className="foo bar {classnames(stateClass)}"> some content </div>

Chỉ để truyền cảm hứng

yếu tố khai báo helper và sử dụng nó togglephương pháp

(DOMToken​List)classList.toggle(class,condition)

thí dụ:

const classes = document.createElement('span').classList; 

function classstate(obj){
  for( let n in obj) classes.toggle(n,obj[n]);
 return classes; 
}

4

Giải pháp thanh lịch hơn, tốt hơn cho bảo trì và dễ đọc:

const classNames = ['js-btn-connect'];

if (isSelected) { classNames.push('is-selected'); }

<Element className={classNames.join(' ')}/>

3

bạn có thể sử dụng cái này:

<div className={"btn-group pull-right" + (this.props.showBulkActions ? ' show' : ' hidden')}>

2

Điều này sẽ làm việc cho bạn

var TopicNav = React.createClass({
render: function() {

let _myClasses = `btn-group pull-right {this.props.showBulkActions?'show':'hidden'}`;

return (
            ...
            <div className={_myClasses}>
               ...
            </div>
    );
  }
});

1

Bạn có thể sử dụng gói npm này . Nó xử lý tất cả mọi thứ và có các tùy chọn cho các lớp tĩnh và động dựa trên một biến hoặc một hàm.

// Support for string arguments
getClassNames('class1', 'class2');

// support for Object
getClassNames({class1: true, class2 : false});

// support for all type of data
getClassNames('class1', 'class2', null, undefined, 3, ['class3', 'class4'], { 
    class5 : function() { return false; },
    class6 : function() { return true; }
});

<div className={getClassNames('show', {class1: true, class2 : false})} /> // "show class1"

1

Dựa trên giá trị của this.props.showBulkActionsbạn có thể chuyển đổi các lớp động như sau.

<div ...{...this.props.showBulkActions 
? { className: 'btn-group pull-right show' } 
: { className: 'btn-group pull-right hidden' }}>

1

Tôi muốn thêm rằng bạn cũng có thể sử dụng một nội dung biến như một phần của lớp

<img src={src} alt="Avatar" className={"img-" + messages[key].sender} />

Bối cảnh là một cuộc trò chuyện giữa bot và người dùng và các kiểu thay đổi tùy thuộc vào người gửi, đây là kết quả của trình duyệt:

<img src="http://imageurl" alt="Avatar" class="img-bot">

1

Điều này hữu ích khi bạn có nhiều hơn một lớp để chắp thêm. Bạn có thể tham gia tất cả các lớp trong mảng với một khoảng trắng.

const visibility = this.props.showBulkActions ? "show" : ""
<div className={["btn-group pull-right", visibility].join(' ')}>

1

Thay thế:

<div className="btn-group pull-right {this.props.showBulkActions ? 'show' : 'hidden'}">`

với:

<div className={`btn-group pull-right ${this.props.showBulkActions ? 'show' : 'hidden'}`}


0

Tôi đã tìm thấy điều này giải thích cách thực hiện với một ternary và với Thư viện Classnames

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.