Динамический атрибут в ReactJS

93

Я хочу динамически включать / опускать атрибут disabled в элементе кнопки. Я видел множество примеров значений динамических атрибутов, но не самих атрибутов. У меня есть следующая функция рендеринга:

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

Это вызывает ошибку синтаксического анализа из-за символа "{". Как я могу включить / опустить атрибут disabled на основе (логического) результата AppStore.cartIsEmpty ()?

Тимми
источник

Ответы:

172

Самый простой способ добавить дополнительные атрибуты (включая disabledи другие, которые вы, возможно, захотите использовать) в настоящее время - использовать атрибуты распространения 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'));

Используя атрибуты распространения, вы можете динамически добавлять (или переопределять) любые атрибуты, которые вам нужны, с помощью экземпляра объекта javascript. В моем примере выше код создает disabledключ ( disabledв данном случае со значением), когда disabledсвойство передается Helloэкземпляру компонента.

Если вы хотите только использовать disabled, этот ответ подойдет.

WiredPrairie
источник
После этого CSS как: a[disabled] { pointer-events: none; }остановит действия над элементом / компонентом
Timbo
49

Вы можете передать disabledатрибуту логическое значение .

render: function() {
    return <button disabled={AppStore.cartIsEmpty()}>Clear cart</button>
}
Александр Киршенберг
источник
8
нет, ты не можешь. наличие атрибута disabled полностью отключает кнопку. см. http://jsfiddle.net/ttjhyvmt/
Тимми
20
React достаточно умен, чтобы условно установить disabledатрибут в итоговом
Александр Киршенберг
2
не знаю, как я это пропустил, спасибо! хотя это работает для моего конкретного случая, я принял другой ответ, который опускает / включает атрибуты
Тимми
1
Однако были проблемы с IE11, мы не использовали последнюю версию реакции. Ответ на атрибуты распространения JSX сработал.
LessQuesar
24

Я использую React 16, и у меня это работает (где boolваш тест):

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

По сути, на основе test ( bool) вы возвращаете объект с атрибутом или возвращаете пустой объект.

Кроме того, если вам нужно добавить или опустить несколько атрибутов, вы можете сделать это:

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

Для более детального управления атрибутами я предлагаю вам предварительно создать объект с атрибутами вне JSX (или без них).

Люк
источник
Спасибо за этот простой, но очень полезный ответ!
tommygun
4

Более чистый способ создания динамических атрибутов, который работает для любых атрибутов, -

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

Вызовите свой компонент реакции, например,

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

Подсказки :

  1. Вы можете иметь dynamicAttributesфункцию в общем месте / утилитах и ​​импортировать ее для использования во всех компонентах

  2. вы можете передать значение, nullчтобы не отображать динамический атрибут

Венкат Редди
источник
Почему бы не сделать вот так: <ReactComponent {... {"data-url": dataURL}} />? это проще и никаких "dynamicAttributes" не требуется
gdbdable
Если атрибут равен нулю, мы не хотим реагировать на рендеринг этого атрибута. пример: "data-modal": null, мы не хотим реагировать на показ data-model = "null". в этом случае мой приведенный выше код даже не отображает атрибут, то есть динамический атрибут, основанный на значении.
Venkat Reddy
4

Намного чище, чем принятое решение, это решение, о котором упоминал AnilRedshift, но которое я расширю.

Проще говоря, атрибуты HTML имеют имя и значение. В сокращении вы можете использовать это имя только для «отключен», «несколько» и т. Д. Но полная версия все еще работает и позволяет React работать предпочтительным образом.

disabled={disabled ? 'disabled' : undefined} это наиболее разборчивое решение.

jhchnc
источник
3

Я использовал следующую версию:

<button disabled={disabled ? 'disabled' : undefined}>
    Click me (or dont)
</button>
АнилРедшифт
источник
Использование undefined в вашем коде - плохая практика. Это также не нужно, так как вы можете просто написать <button disabled = {disabled}>, поскольку disabled - это логическая переменная, которая возвращает true или false
Рафаэль Пинель
Почему undefined - плохая практика? Цитируйте, если возможно. Также, возможно, сейчас реагирует правильно, обрабатывает bools, но на момент написания ваше предложение не будет работать правильно
AnilRedshift
2

Вы можете найти что-то подобное в документации.

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

В вашем случае может быть что-то вроде этого

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

Этот код использует ES6, но я думаю, вы поняли.

Это круто, потому что вы можете передать этому компоненту многие другие атрибуты, и он все равно будет работать.

user3552712
источник
2

Простой и понятный способ сделать это

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

отключен должен исходить от такого реквизита

<MyComponent disabled />
Йогиё
источник
0

Сначала вы можете просто проверить

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

Примечание: ** значение disabled не является String, оно должно быть логическим .

Теперь о динамике. Вы можете просто написать

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

Как видите, я использую свойство disabled, и в фигурных скобках это может быть локальная переменная / переменная состояния. Переменная disableсодержит значения true / false.

винаяк лахотия
источник
-3

Это может сработать, проблема с disabled в том, что для него нельзя просто установить логическое значение.

if(AppStore.cartIsEmpty()){
  return "<button disabled>Clear cart</button>"
}
else
{
  return "<button>Clear cart</button>"
}
ЛедянойЯркий
источник
Я боялся, что мне придется прибегнуть к этому ... Я подожду, чтобы посмотреть, есть ли у кого-нибудь еще предложения, прежде чем принять ваш ответ
Тимми