Thuộc tính động trong ReactJS


92

Tôi muốn tự động bao gồm / bỏ qua thuộc tính bị vô hiệu hóa trên một phần tử nút. Tôi đã thấy rất nhiều ví dụ về các giá trị thuộc tính động, nhưng không phải về bản thân các thuộc tính. Tôi có chức năng kết xuất sau:

render: function() {
    var maybeDisabled = AppStore.cartIsEmpty() ? "disabled" : "";
    return <button {maybeDisabled}>Clear cart</button>
}

Điều này gây ra lỗi phân tích cú pháp do ký tự "{". Làm cách nào tôi có thể bao gồm / bỏ qua thuộc tính đã tắt dựa trên kết quả (boolean) của AppStore.cartIsEmpty ()?

Câu trả lời:


168

Cách tốt nhất để thêm các thuộc tính tùy chọn (bao gồm disabledvà những thuộc tính khác mà bạn có thể muốn sử dụng) hiện là sử dụng các thuộc tính trải rộng JSX :

var Hello = React.createClass({
    render: function() {
        var opts = {};
        if (this.props.disabled) {
            opts['disabled'] = 'disabled';
        }
        return <button {...opts}>Hello {this.props.name}</button>;
    }
});

React.render((<div><Hello name="Disabled" disabled='true' />
    <Hello name="Enabled"  />
</div>)
, document.getElementById('container'));

Bằng cách sử dụng thuộc tính lây lan, bạn có thể thêm (hoặc ghi đè) động bất kỳ thuộc tính nào bạn muốn bằng cách sử dụng phiên bản đối tượng javascript. Trong ví dụ của tôi ở trên, mã tạo một disabledkhóa (với một disabledgiá trị trong trường hợp này) khi thuộc disabledtính được chuyển cho Hellocá thể thành phần.

Nếu bạn chỉ muốn sử dụng disabled, câu trả lời này hoạt động tốt.


Một bước nữa, CSS như: a[disabled] { pointer-events: none; }sẽ ngừng các hành động trên một yếu tố / thành phần
timbo

49

Bạn có thể chuyển một boolean cho disabledthuộc tính.

render: function() {
    return <button disabled={AppStore.cartIsEmpty()}>Clear cart</button>
}

8
không, bạn không thể. sự hiện diện của thuộc tính bị vô hiệu hóa sẽ vô hiệu hóa nút hoàn toàn. xem http://jsfiddle.net/ttjhyvmt/
Timmy

20
Phản ứng là đủ thông minh để có điều kiện thiết lập các disabledthuộc tính trên kết quả HTML tùy thuộc vào giá trị mà bạn thông qua jsfiddle.net/kb3gN/10379
Alexandre Kirszenberg

2
không chắc chắn làm thế nào tôi đã bỏ lỡ điều đó, cảm ơn bạn! trong khi công trình này đối với trường hợp cụ thể của tôi, tôi đã chấp nhận một câu trả lời mà bỏ qua / bao gồm các thuộc tính
Timmy

1
Tuy nhiên, đã gặp sự cố với IE11, chúng tôi đã không sử dụng phản ứng mới nhất. Câu trả lời thuộc tính trải rộng JSX đã hoạt động.
LessQuesar

24

Tôi đang sử dụng React 16 và điều này phù hợp với tôi ( boolthử nghiệm của bạn ở đâu ):

<fieldset {...(bool ? {disabled:true} : {})}>

Về cơ bản, dựa trên test ( bool) bạn trả về một đối tượng có thuộc tính hoặc bạn trả về một đối tượng trống.

Ngoài ra, nếu bạn cần thêm hoặc bỏ qua nhiều thuộc tính, bạn có thể thực hiện việc này:

<fieldset {...(bool ? {disabled:true} : {})} {...(bool ? {something:'123'} : {})}>

Để quản lý thuộc tính phức tạp hơn, tôi khuyên bạn nên cài đặt trước đối tượng với (hoặc không) các thuộc tính bên ngoài JSX.


Cảm ơn vì câu trả lời đơn giản nhưng rất hữu ích đó!
tommygun

4

Cách rõ ràng hơn để thực hiện các thuộc tính động hoạt động cho bất kỳ thuộc tính nào là

function dynamicAttributes(attribute, value){
  var opts = {};
  if(typeof value !== 'undefined' && value !== null) {
    opts['"'+attribute+'"'] = value;
    return opts;
  }
  return false;
};

Gọi trong thành phần phản ứng của bạn như sau

<ReactComponent {...dynamicAttributes("disabled",false)}
{...dynamicAttributes("data-url",dataURL)}
{...dynamicAttributes("data-modal",true)} />

Lời khuyên :

  1. Bạn có thể có dynamicAttributeschức năng ở một nơi / tiện ích chung và nhập nó để sử dụng nó trên tất cả các thành phần

  2. bạn có thể chuyển giá trị nullđể không hiển thị thuộc tính động


Tại sao không làm như thế này: <ReactComponent {... {"data-url": dataURL}} />? nó đơn giản hơn và không cần "dynamicAttributes"
gdbdable

Trong trường hợp thuộc tính là null, chúng tôi không muốn phản ứng để hiển thị thuộc tính đó. ví dụ: "data-modal": null, chúng tôi không muốn phản ứng hiển thị data-model = "null". trong trường hợp này, đoạn mã trên của tôi thậm chí sẽ không hiển thị thuộc tính, tức là thuộc tính động dựa trên giá trị.
Venkat Reddy

2

Bạn có thể tìm thấy một cái gì đó tương tự như thế này tại tài liệu.

https://facebook.github.io/react/docs/transferring-props.html

Trong trường hợp của bạn có thể là một cái gì đó như thế này

function MyComponent(props) {
    let { disabled, ...attrs } = props;
    if (disabled) {
        // thus, it will has the disabled attribute only if it
        // is disabled
        attrs = {
            ...attrs,
            disabled: true
        }
    };

    return (
        <button {...attrs}>MyLabel</button>
    )
}

Mã này đang sử dụng ES6, nhưng tôi biết bạn có ý tưởng.

Điều này thật tuyệt vì bạn có thể chuyển nhiều thuộc tính khác cho thành phần này và nó vẫn hoạt động.


2

Phiên bản tôi đã sử dụng là:

<button disabled={disabled ? 'disabled' : undefined}>
    Click me (or dont)
</button>

Việc sử dụng không xác định trong mã của bạn là một thực tiễn xấu. Nó cũng là không cần thiết khi bạn chỉ đơn giản là có thể viết <button disabled = {} khuyết tật> như tàn tật là một biến boolean hơn việc quay lại đúng hay sai
Raphael Pinel

Tại sao không xác định được thực hành xấu? Trích dẫn nếu có thể. Cũng có thể phản ứng đúng cách xử lý các bools ngay bây giờ nhưng tại thời điểm viết đề xuất của bạn sẽ không hoạt động chính xác
AnilRedshift

2

Một cách đơn giản và sạch sẽ để làm điều đó

<button {...disabled && {disabled: true}}>Clear cart</button>

bị vô hiệu hóa nên đến từ các đạo cụ như thế này

<MyComponent disabled />

1

Gọn gàng hơn nhiều so với giải pháp được chấp nhận là giải pháp mà AnilRedshift đã đề cập, nhưng tôi sẽ mở rộng thêm.

Nói một cách đơn giản, các thuộc tính HTML có một tên và một giá trị. Như một cách viết tắt, bạn chỉ có thể sử dụng tên cho "bị vô hiệu hóa", "nhiều", v.v. Nhưng phiên bản tốc ký vẫn hoạt động và cho phép React hoạt động theo cách ưu tiên.

disabled={disabled ? 'disabled' : undefined} là giải pháp rõ ràng nhất.


0

Đầu tiên bạn có thể kiểm tra

<button disabled={true}>Button 1</button>
<button disabled={false}>Button 2</button>

Lưu ý: ** giá trị bị vô hiệu hóa không phải là Chuỗi, nó phải là Boolean .

Bây giờ cho động. Bạn chỉ có thể viết

<button type="button" disabled={disable}  
        onClick={()=>this.setSelectValue('sms')} >{this.state.sms}</button>

Như bạn có thể thấy, tôi đang sử dụng thuộc tính bị vô hiệu hóa và trong dấu ngoặc nhọn, nó có thể là biến cục bộ / trạng thái var. Biến disablechứa các giá trị true / false.


-3

Điều này có thể hoạt động, vấn đề với bị vô hiệu hóa là người ta không thể chỉ đơn giản đặt boolean cho nó.

if(AppStore.cartIsEmpty()){
  return "<button disabled>Clear cart</button>"
}
else
{
  return "<button>Clear cart</button>"
}

Tôi sợ tôi có thể phải dùng đến này .. Tôi sẽ chờ đợi để xem nếu bất cứ ai có bất cứ đề nghị trước khi chấp nhận câu trả lời của bạn
Timmy
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.