Dynamic attribute in ReactJS

Reactjs

Reactjs Problem Overview


I want to dynamically include/omit the disabled attribute on a button element. I have seen plenty of examples of dynamic attribute values, but not of attributes themselves. I have the following render function:

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

This throws a parse error because of the "{" character. How can I include/omit the disabled attribute based on the (boolean) result of AppStore.cartIsEmpty()?

Reactjs Solutions


Solution 1 - Reactjs

The cleanest way to add optional attributes (including disabled and others you might want to use) is currently to use JSX spread attributes:

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

By using spread attributes, you can dynamically add (or override) whatever attributes you'd like by using a javascript object instance. In my example above, the code creates a disabled key (with a disabled value in this case) when the disabled property is passed to the Hello component instance.

If you only want to use disabled though, this answer works well.

Solution 2 - Reactjs

You can pass a boolean to the disabled attribute.

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

function Test() {
  return (
    <div>
      <button disabled={false}>Clear cart</button>
      <button disabled={true}>Clear cart</button>
    </div>
  );
}

ReactDOM.render(<Test />, document.querySelector("#test-container"));
console.log(Array.from(document.querySelectorAll("button")));

<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="test-container"></div>

Solution 3 - Reactjs

I'm using React 16 and this works for me (where bool is your test):

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

Basically, based on the test (bool) you return an object with the conditional attributes or you don't.

Also, if you need to add or omit multiple attributes you can do this:

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

For more elaborate attribute managed I suggest you prefab the object with (or without) the attributes outside of JSX.

Solution 4 - Reactjs

Far cleaner than the accepted solution is the solution which AnilRedshift mentioned, but which I'll expand on.

Simply put, HTML attributes have a name and a value. As a shorthand, you can use the name only for "disabled", "multiple", etc. But the longhand version still works, and allows for React to work in it's preferred way.

disabled={disabled ? 'disabled' : undefined} is the most legible solution.

Solution 5 - Reactjs

The version I used was:

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

Solution 6 - Reactjs

More cleaner way of doing dynamic attributes which works for any attributes is

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

Call in your react component like following

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

Tips :

  1. You could have dynamicAttributes function in a common place/utilities and import it to use it across all components

  2. you could pass value as null to not render dynamic attribute

Solution 7 - Reactjs

A simple and clean way of doing it

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

disabled should come from props like this

<MyComponent disabled />

Solution 8 - Reactjs

You can find something similar to this at the documentation.

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

In your case could be something like this

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

This code is using ES6, but I thing you got the idea.

This is cool because you can pass many others attributes to this component and it will still work.

Solution 9 - Reactjs

First you can simply check

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

Note: **disabled value is not String, it should be Boolean.

Now for dynamic. You can simply write

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

As you can see I am using disabled property and in curly brackets it can be local variable/state var. The variable disable contains values true/false.

Solution 10 - Reactjs

This could work, problem with disabled is one could not simply set boolean for it.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTimmyView Question on Stackoverflow
Solution 1 - ReactjsWiredPrairieView Answer on Stackoverflow
Solution 2 - ReactjsAlexandre KirszenbergView Answer on Stackoverflow
Solution 3 - ReactjsLukeView Answer on Stackoverflow
Solution 4 - ReactjsjhchncView Answer on Stackoverflow
Solution 5 - ReactjsAnilRedshiftView Answer on Stackoverflow
Solution 6 - ReactjsVenkat ReddyView Answer on Stackoverflow
Solution 7 - ReactjsYogiyoView Answer on Stackoverflow
Solution 8 - Reactjsuser3552712View Answer on Stackoverflow
Solution 9 - Reactjsvinayak lakhotiyaView Answer on Stackoverflow
Solution 10 - ReactjsIcyBrightView Answer on Stackoverflow