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 ()?

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.


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

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.


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


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.


2

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

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

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

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.


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.


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

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.