Attribut dynamique dans ReactJS

92

Je souhaite inclure / omettre dynamiquement l'attribut désactivé sur un élément de bouton. J'ai vu de nombreux exemples de valeurs d'attributs dynamiques, mais pas d'attributs eux-mêmes. J'ai la fonction de rendu suivante:

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

Cela génère une erreur d'analyse à cause du caractère "{". Comment puis-je inclure / omettre l'attribut désactivé en fonction du résultat (booléen) de AppStore.cartIsEmpty ()?

Timmy
la source

Réponses:

168

Le moyen le plus simple d'ajouter des attributs facultatifs (y compris disabledet d'autres que vous pourriez vouloir utiliser) est actuellement d'utiliser les attributs de propagation 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'));

En utilisant des attributs de diffusion, vous pouvez ajouter (ou remplacer) dynamiquement les attributs de votre choix en utilisant une instance d'objet javascript. Dans mon exemple ci-dessus, le code crée une disabledclé (avec une disabledvaleur dans ce cas) lorsque la disabledpropriété est transmise à l' Helloinstance du composant.

Si vous ne souhaitez utiliser disabledque, cette réponse fonctionne bien.

FilairePrairie
la source
Une fois en place, CSS comme: a[disabled] { pointer-events: none; }arrêtera les actions sur un élément / composant
timbo
49

Vous pouvez passer un booléen à l' disabledattribut.

render: function() {
    return <button disabled={AppStore.cartIsEmpty()}>Clear cart</button>
}
Alexandre Kirszenberg
la source
8
non tu ne peux pas. la présence de l'attribut désactivé désactive complètement le bouton. voir http://jsfiddle.net/ttjhyvmt/
Timmy
20
React est assez intelligent pour définir conditionnellement l' disabledattribut sur le HTML résultant en fonction de la valeur que vous avez passée jsfiddle.net/kb3gN/10379
Alexandre Kirszenberg
2
Je ne sais pas comment j'ai raté ça, merci! bien que cela fonctionne pour mon cas spécifique, j'ai accepté une autre réponse qui omet / inclut des attributs
Timmy
1
Eu des problèmes avec IE11, cependant, nous n'utilisions pas la dernière réaction. La réponse des attributs de propagation JSX a fonctionné.
LessQuesar
24

J'utilise React 16 et cela fonctionne pour moi (où boolest votre test):

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

Fondamentalement, sur la base du test ( bool), vous retournez un objet avec l'attribut ou vous retournez un objet vide.

De plus, si vous devez ajouter ou omettre plusieurs attributs, vous pouvez le faire:

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

Pour des attributs plus élaborés, je vous suggère de préfabriquer l'objet avec (ou sans) les attributs en dehors de JSX.

Luke
la source
Merci pour cette réponse simple mais très utile!
tommygun
4

Une manière plus propre de créer des attributs dynamiques qui fonctionne pour tous les attributs est

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

Appelez votre composant de réaction comme suit

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

Conseils :

  1. Vous pouvez avoir une dynamicAttributesfonction dans un endroit / utilitaires communs et l'importer pour l'utiliser dans tous les composants

  2. vous pouvez passer la valeur nullpour ne pas rendre l'attribut dynamique

Venkat Reddy
la source
Pourquoi ne pas faire comme ça: <ReactComponent {... {"data-url": dataURL}} />? c'est plus simple et pas de "dynamicAttributes" nécessaire
gdbdable
Si l'attribut est nul, nous ne voulons pas réagir pour rendre cet attribut. exemple: "data-modal": null nous ne voulons pas réagir pour afficher data-model = "null". dans ce cas, mon code ci-dessus ne montrera même pas l'attribut, c'est-à-dire l'attribut dynamique basé sur la valeur.
Venkat Reddy
2

Vous pouvez trouver quelque chose de similaire dans la documentation.

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

Dans votre cas pourrait être quelque chose comme ça

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

Ce code utilise ES6, mais je pense que vous avez l'idée.

C'est cool car vous pouvez transmettre de nombreux autres attributs à ce composant et cela fonctionnera toujours.

user3552712
la source
2

La version que j'ai utilisée était:

<button disabled={disabled ? 'disabled' : undefined}>
    Click me (or dont)
</button>
AnilRedshift
la source
C'est une mauvaise pratique d'utiliser undefined dans votre code. Il est également inutile car vous pouvez simplement écrire <button disabled = {disabled}> car disabled est une variable booléenne qui renvoie vrai ou faux
Raphael Pinel
Pourquoi une mauvaise pratique indéfinie? Citation si possible. Réagissez peut-être aussi correctement gère les booléens maintenant, mais au moment de l'écriture, votre suggestion ne fonctionnerait pas correctement
AnilRedshift
2

Une façon simple et propre de le faire

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

désactivé devrait provenir d'accessoires comme celui-ci

<MyComponent disabled />
Yogiyo
la source
1

Bien plus propre que la solution acceptée est la solution mentionnée par AnilRedshift, mais sur laquelle je vais développer.

En termes simples, les attributs HTML ont un nom et une valeur. En abrégé, vous ne pouvez utiliser le nom que pour «désactivé», «multiple», etc. Mais la version longue fonctionne toujours et permet à React de fonctionner de sa manière préférée.

disabled={disabled ? 'disabled' : undefined} est la solution la plus lisible.

jhchnc
la source
0

Tout d'abord, vous pouvez simplement vérifier

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

Remarque: ** la valeur désactivée n'est pas une chaîne, elle doit être booléenne .

Maintenant pour dynamique. Vous pouvez simplement écrire

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

Comme vous pouvez le voir, j'utilise la propriété disabled et entre accolades, il peut s'agir d'une variable locale / var d'état. La variable disablecontient des valeurs vrai / faux.

vinayak lakhotiya
la source
-3

Cela pourrait fonctionner, le problème avec désactivé est que l'on ne peut pas simplement définir un booléen pour cela.

if(AppStore.cartIsEmpty()){
  return "<button disabled>Clear cart</button>"
}
else
{
  return "<button>Clear cart</button>"
}
IcyBright
la source
J'avais peur de devoir recourir à cela. J'attendrai de voir si quelqu'un d'autre a des suggestions avant d'accepter votre réponse
Timmy