Dynamisches Attribut in ReactJS

92

Ich möchte das deaktivierte Attribut eines Schaltflächenelements dynamisch einschließen / weglassen. Ich habe viele Beispiele für dynamische Attributwerte gesehen, aber nicht für Attribute selbst. Ich habe die folgende Renderfunktion:

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

Dies löst einen Analysefehler aufgrund des Zeichens "{" aus. Wie kann ich das deaktivierte Attribut basierend auf dem (booleschen) Ergebnis von AppStore.cartIsEmpty () einschließen / weglassen?

Timmy
quelle

Antworten:

166

Die sauberste Methode zum Hinzufügen optionaler Attribute (einschließlich disabledund anderer, die Sie möglicherweise verwenden möchten) ist derzeit die Verwendung von JSX-Spread-Attributen :

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'));

Mithilfe von Spread-Attributen können Sie mithilfe einer Javascript-Objektinstanz beliebig beliebige Attribute dynamisch hinzufügen (oder überschreiben). In meinem obigen Beispiel erstellt der Code einen disabledSchlüssel ( disabledin diesem Fall mit einem Wert), wenn die disabledEigenschaft an die HelloKomponenteninstanz übergeben wird.

Wenn Sie nur verwenden möchten , disabledaber dies funktioniert Antwort gut.

WiredPrairie
quelle
Sobald es eingerichtet ist, a[disabled] { pointer-events: none; }stoppt CSS wie: Aktionen für ein Element / eine Komponente
Timbo
49

Sie können dem disabledAttribut einen Booleschen Wert übergeben.

render: function() {
    return <button disabled={AppStore.cartIsEmpty()}>Clear cart</button>
}
Alexandre Kirszenberg
quelle
8
Nein, du kannst nicht. Das Vorhandensein des Attributs disabled deaktiviert die Schaltfläche vollständig. siehe http://jsfiddle.net/ttjhyvmt/
Timmy
20
React ist klug genug, um das disabledAttribut für den resultierenden HTML- Code
Alexandre Kirszenberg
2
Ich bin mir nicht sicher, wie ich das verpasst habe, danke! Während dies für meinen speziellen Fall funktioniert, habe ich eine andere Antwort akzeptiert, bei der Attribute weggelassen / eingeschlossen werden
Timmy
1
Hatte Probleme mit IE11, wir verwendeten jedoch nicht die neueste Reaktion. Die Antwort auf die JSX-Spread-Attribute hat funktioniert.
LessQuesar
24

Ich benutze React 16 und das funktioniert bei mir (wo boolist dein Test):

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

Grundsätzlich geben Sie basierend auf test ( bool) ein Objekt mit dem Attribut zurück oder Sie geben ein leeres Objekt zurück.

Wenn Sie mehrere Attribute hinzufügen oder weglassen müssen, können Sie Folgendes tun:

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

Für eine ausführlichere Verwaltung von Attributen empfehle ich, das Objekt mit (oder ohne) Attributen außerhalb von JSX vorzufertigen.

Luke
quelle
Vielen Dank für diese einfache, aber sehr hilfreiche Antwort!
Tommygun
4

Eine sauberere Art, dynamische Attribute zu erstellen, die für alle Attribute funktioniert, ist

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

Rufen Sie Ihre Reaktionskomponente wie folgt auf

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

Tipps:

  1. Sie können eine dynamicAttributesFunktion an einem gemeinsamen Ort / in Dienstprogrammen haben und diese importieren, um sie für alle Komponenten zu verwenden

  2. Sie können einen Wert übergeben, nullum keine dynamischen Attribute zu rendern

Venkat Reddy
quelle
Warum nicht so: <ReactComponent {... {"data-url": dataURL}} />? es ist einfacher und es werden keine "dynamicAttributes" benötigt
gdbdable
Wenn das Attribut null ist, möchten wir nicht reagieren, um dieses Attribut zu rendern. Beispiel: "data-modal": null Wir möchten nicht reagieren, um data-model = "null" anzuzeigen. In diesem Fall zeigt mein obiger Code nicht einmal das Attribut, dh das dynamische Attribut basierend auf dem Wert.
Venkat Reddy
2

Ähnliches finden Sie in der Dokumentation.

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

In Ihrem Fall könnte so etwas sein

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

Dieser Code verwendet ES6, aber ich denke, Sie haben die Idee.

Dies ist cool, da Sie dieser Komponente viele andere Attribute übergeben können und sie weiterhin funktioniert.

user3552712
quelle
2

Die Version, die ich verwendet habe, war:

<button disabled={disabled ? 'disabled' : undefined}>
    Click me (or dont)
</button>
AnilRedshift
quelle
Es ist eine schlechte Praxis, undefiniert in Ihrem Code zu verwenden. Es ist auch unnötig, da Sie einfach <button disabled = {disabled}> schreiben könnten, da disabled eine boolesche Variable ist, die true oder false zurückgibt
Raphael Pinel
Warum ist undefinierte schlechte Praxis? Wenn möglich zitieren. Vielleicht reagieren Sie jetzt auch richtig mit Bools, aber zum Zeitpunkt des Schreibens würde Ihr Vorschlag nicht richtig funktionieren
AnilRedshift
2

Eine einfache und saubere Art, es zu tun

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

Behinderte sollten von solchen Requisiten kommen

<MyComponent disabled />
Yogiyo
quelle
1

Weitaus sauberer als die akzeptierte Lösung ist die von AnilRedshift erwähnte Lösung, auf die ich jedoch näher eingehen werde.

Einfach ausgedrückt haben HTML-Attribute einen Namen und einen Wert. Als Abkürzung können Sie den Namen nur für "deaktiviert", "mehrfach" usw. verwenden. Die Langhandversion funktioniert jedoch weiterhin und ermöglicht es React, auf die bevorzugte Weise zu arbeiten.

disabled={disabled ? 'disabled' : undefined} ist die am besten lesbare Lösung.

jhchnc
quelle
0

Zuerst können Sie einfach überprüfen

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

Hinweis: ** deaktivierter Wert ist kein String, sondern sollte boolesch sein .

Nun zur Dynamik. Sie können einfach schreiben

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

Wie Sie sehen können, verwende ich die Eigenschaft disabled und in geschweiften Klammern kann es sich um eine lokale Variable / einen Status var handeln. Die Variable disableenthält die Werte true / false.

vinayak lakhotiya
quelle
-3

Dies könnte funktionieren, das Problem mit deaktiviert ist, dass man nicht einfach einen Booleschen Wert dafür festlegen kann.

if(AppStore.cartIsEmpty()){
  return "<button disabled>Clear cart</button>"
}
else
{
  return "<button>Clear cart</button>"
}
IcyBright
quelle
Ich hatte Angst, ich könnte darauf zurückgreifen müssen. Ich werde abwarten, ob jemand andere Vorschläge hat, bevor ich Ihre Antwort akzeptiere
Timmy