Atributo dinámico en ReactJS

92

Quiero incluir / omitir dinámicamente el atributo deshabilitado en un elemento de botón. He visto muchos ejemplos de valores de atributos dinámicos, pero no de atributos en sí mismos. Tengo la siguiente función de renderizado:

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

Esto arroja un error de análisis debido al carácter "{". ¿Cómo puedo incluir / omitir el atributo deshabilitado según el resultado (booleano) de AppStore.cartIsEmpty ()?

Timmy
fuente

Respuestas:

168

La forma más limpia de agregar atributos opcionales (incluidos disabledy otros que quizás desee usar) es actualmente usar atributos de extensión 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'));

Al usar atributos de propagación, puede agregar (o anular) dinámicamente los atributos que desee mediante una instancia de objeto javascript. En mi ejemplo anterior, el código crea una disabledclave (con un disabledvalor en este caso) cuando la disabledpropiedad se pasa a la Helloinstancia del componente.

Sin embargo, si solo desea usar disabled, esta respuesta funciona bien.

WiredPrairie
fuente
Una vez en su lugar, CSS como: a[disabled] { pointer-events: none; }detendrá las acciones en un elemento / componente
timbo
49

Puede pasar un booleano al disabledatributo.

render: function() {
    return <button disabled={AppStore.cartIsEmpty()}>Clear cart</button>
}
Alexandre Kirszenberg
fuente
8
No, no puedes. la presencia del atributo desactivado desactiva el botón por completo. ver http://jsfiddle.net/ttjhyvmt/
Timmy
20
React es lo suficientemente inteligente como para establecer condicionalmente el disabledatributo en el HTML resultante según el valor que pasó jsfiddle.net/kb3gN/10379
Alexandre Kirszenberg
2
No estoy seguro de cómo me perdí eso, ¡gracias! Si bien esto funciona para mi caso específico, he aceptado otra respuesta que omite / incluye atributos
Timmy
1
Tuve problemas con IE11, sin embargo, no estábamos usando la última reacción. La respuesta de los atributos de extensión JSX funcionó.
LessQuesar
24

Estoy usando React 16 y esto funciona para mí (dónde boolestá tu prueba):

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

Básicamente, según la prueba ( bool), devuelve un objeto con el atributo o devuelve un objeto vacío.

Además, si necesita agregar u omitir varios atributos, puede hacer esto:

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

Para un atributo administrado más elaborado, le sugiero que prefabrica el objeto con (o sin) los atributos fuera de JSX.

Luke
fuente
¡Gracias por esa respuesta simple pero muy útil!
tommygun
4

Una forma más limpia de hacer atributos dinámicos que funciona para cualquier atributo es

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

Llame a su componente de reacción como sigue

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

Consejos :

  1. Podría tener dynamicAttributesfunciones en un lugar / utilidades comunes e importarlas para usarlas en todos los componentes

  2. podría pasar un valor nullpara no representar el atributo dinámico

Venkat Reddy
fuente
¿Por qué no hacer esto: <ReactComponent {... {"data-url": dataURL}} />? es más simple y no se necesitan "atributos dinámicos"
gdbdable
En caso de que el atributo sea nulo, no queremos reaccionar para representar ese atributo. ejemplo: "data-modal": null no queremos reaccionar para mostrar data-model = "null". en este caso, mi código anterior ni siquiera mostrará el atributo, es decir, el atributo dinámico basado en el valor.
Venkat Reddy
2

Puede encontrar algo similar a esto en la documentación.

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

En tu caso podría ser algo como esto

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

Este código usa ES6, pero creo que tienes la idea.

Esto es genial porque puede pasar muchos otros atributos a este componente y seguirá funcionando.

usuario3552712
fuente
2

La versión que usé fue:

<button disabled={disabled ? 'disabled' : undefined}>
    Click me (or dont)
</button>
AnilRedhift
fuente
Es una mala práctica utilizar undefined en su código. También es innecesario ya que simplemente podría escribir <button disabled = {disabled}> ya que disabled es una variable booleana que devuelve verdadero o falso
Raphael Pinel
¿Por qué es una mala práctica indefinida? Cita si es posible. También quizás reaccione correctamente maneja bools ahora, pero en el momento de escribir su sugerencia no funcionaría correctamente
AnilRedshift
2

Una forma sencilla y limpia de hacerlo

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

discapacitado debe provenir de accesorios como este

<MyComponent disabled />
Yogiyo
fuente
1

Mucho más limpia que la solución aceptada es la solución que mencionó AnilRedshift, pero que ampliaré.

En pocas palabras, los atributos HTML tienen un nombre y un valor. Como forma abreviada, puede usar el nombre solo para "desactivado", "múltiple", etc. Pero la versión a mano derecha todavía funciona y permite que React funcione de la manera que prefiera.

disabled={disabled ? 'disabled' : undefined} es la solución más legible.

jhchnc
fuente
0

Primero, simplemente puede verificar

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

Nota: ** el valor deshabilitado no es String, debe ser booleano .

Ahora para la dinámica. Simplemente puedes escribir

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

Como puede ver, estoy usando una propiedad deshabilitada y entre llaves puede ser una variable local / var de estado. La variable disablecontiene valores verdadero / falso.

vinayak lakhotiya
fuente
-3

Esto podría funcionar, el problema con disabled es que no se puede simplemente establecer boolean para ello.

if(AppStore.cartIsEmpty()){
  return "<button disabled>Clear cart</button>"
}
else
{
  return "<button>Clear cart</button>"
}
IcyBright
fuente
Tenía miedo de tener que recurrir a esto ... Esperaré a ver si alguien más tiene alguna sugerencia antes de aceptar su respuesta
Timmy