Есть ли способ добавить атрибуты в компонент React, только если выполняется определенное условие?

Я должен добавить обязательные атрибуты и атрибуты readOnly для элементов формы на основе вызова Ajax после рендеринга, но я не вижу, как это решить, поскольку readOnly = "false" - это не то же самое, что полное исключение атрибута.

Пример ниже должен объяснить, что я хочу, но это не сработает (Ошибка синтаксического анализа: неожиданный идентификатор).

var React = require('React');

var MyOwnInput = React.createClass({
    render: function () {
        return (
            <div>
                <input type="text" onChange={this.changeValue} value={this.getValue()} name={this.props.name}/>
            </div>
        );
    }
});

module.exports = React.createClass({
    getInitialState: function () {
        return {
            isRequired: false
        }
    },
    componentDidMount: function () {
        this.setState({
            isRequired: true
        });
    },
    render: function () {
        var isRequired = this.state.isRequired;

        return (
            <MyOwnInput name="test" {isRequired ? "required" : ""} />
        );
    }
});
668
Remi Sture 1 Июл 2015 в 17:07

11 ответов

Лучший ответ

Очевидно, для определенных атрибутов React достаточно умен, чтобы пропустить атрибут, если значение, которое вы передаете ему, неверно. Например:

var InputComponent = React.createClass({
    render: function() {
        var required = true;
        var disabled = false;

        return (
            <input type="text" disabled={disabled} required={required} />
        );
    }
});

Приведет к:

<input type="text" required>

Обновление . Если кому-то интересно, как и почему это происходит, подробности можно найти в исходном коде ReactDOM, в частности в строках 30 и 167 DOMProperty.js.

507
juandemarco 26 Сен 2019 в 18:50

Учитывая сообщение JSX In Depth , вы можете решить вашу проблему следующим образом:

if (isRequired) {
  return (
    <MyOwnInput name="test" required='required' />
  );
}
return (
    <MyOwnInput name="test" />
);
0
Peter Mortensen 29 Янв 2020 в 01:01

В React вы можете условно визуализировать Компоненты, а также их атрибуты, такие как props, className, id и многое другое.

В React очень полезно использовать троичный оператор, который может помочь вам условно визуализировать компоненты ,

В примере также показано, как условно отобразить Компонент и его атрибут стиля.

Вот простой пример:

class App extends React.Component {
  state = {
    isTrue: true
  };

  render() {
    return (
      <div>
        {this.state.isTrue ? (
          <button style={{ color: this.state.isTrue ? "red" : "blue" }}>
            I am rendered if TRUE
          </button>
        ) : (
          <button>I am rendered if FALSE</button>
        )}
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>
3
Peter Mortensen 29 Янв 2020 в 01:18

Это должно работать, так как ваше состояние изменится после вызова Ajax, а родительский компонент будет перерисован.

render : function () {
    var item;
    if (this.state.isRequired) {
        item = <MyOwnInput attribute={'whatever'} />
    } else {
        item = <MyOwnInput />
    }
    return (
        <div>
            {item}
        </div>
    );
}
7
Peter Mortensen 29 Янв 2020 в 00:59

Если вы используете ECMAScript 6, вы можете просто написать так.

// First, create a wrap object.
const wrap = {
    [variableName]: true
}
// Then, use it
<SomeComponent {...{wrap}} />
10
Peter Mortensen 29 Янв 2020 в 01:12

Допустим, мы хотим добавить пользовательское свойство (используя aria- * или data- *), если условие истинно:

{...this.props.isTrue && {'aria-name' : 'something here'}}

Допустим, мы хотим добавить свойство стиля, если условие истинно:

{...this.props.isTrue && {style : {color: 'red'}}}
18
Peter Mortensen 29 Янв 2020 в 01:11

Вы можете использовать тот же ярлык, который используется для добавления / удаления (частей) компонентов ({isVisible && <SomeComponent />}).

class MyComponent extends React.Component {
  render() {
    return (
      <div someAttribute={someCondition && someValue} />
    );
  }
}
19
GijsjanB 24 Окт 2016 в 14:49

Вот способ, которым я делаю это.

С условным условием :

<Label
    {...{
      text: label,
      type,
      ...(tooltip && { tooltip }),
      isRequired: required
    }}
/>

Я по-прежнему предпочитаю использовать обычный способ передачи подпорок вниз, потому что он более читабелен (на мой взгляд) в случае отсутствия каких-либо условий.

Без условия .

<Label text={label} type={type} tooltip={tooltip} isRequired={required} />
29
Peter Mortensen 29 Янв 2020 в 01:20

Вот альтернатива.

var condition = true;

var props = {
  value: 'foo',
  ...( condition && { disabled: true } )
};

var component = <div { ...props } />;

Или его встроенная версия

var condition = true;

var component = (
  <div
    value="foo"
    { ...( condition && { disabled: true } ) } />
);
81
Peter Mortensen 29 Янв 2020 в 01:09

Ниже приведен пример использования Bootstrap Button через React-Bootstrap (версия 0.32.4):

var condition = true;

return (
  <Button {...(condition ? {bsStyle: 'success'} : {})} />
);

В зависимости от условия будет возвращено {bsStyle: 'success'} или {}. Затем оператор распространения распространит свойства возвращаемого объекта на компонент Button. В ложном случае, поскольку в возвращаемом объекте не существует никаких свойств, компоненту ничего не передается.


Альтернативный способ, основанный на комментарии Энди Полхилла :

var condition = true;

return (
  <Button bsStyle={condition ? 'success' : undefined} />
);

Единственное небольшое отличие состоит в том, что во втором примере объект <Button/> внутреннего компонента props будет иметь ключ bsStyle со значением undefined.

281
Peter Mortensen 29 Янв 2020 в 01:06

ответ juandemarco обычно является правильным, но вот еще один вариант.

Постройте объект так, как вам нравится:

var inputProps = {
  value: 'foo',
  onChange: this.handleChange
};

if (condition)
  inputProps.disabled = true;

Рендеринг со спредом, при желании можно передать и другие реквизиты.

<input
    value="this is overridden by inputProps"
    {...inputProps}
    onChange={overridesInputProps}
 />
369
Peter Mortensen 29 Янв 2020 в 01:03