Реагуйте: вбудований умовно передає властивість компоненту


85

Я хотів би знати, чи є кращий спосіб умовно передати опис, ніж використання оператора if.

Наприклад, зараз у мене є:

var parent = React.createClass({
  propTypes: {
    editable: React.PropTypes.bool.isRequired,
    editableOpts: React.PropTypes.shape({...})
  },
  render: function() {
    if(this.props.editable) {
      return (
        <Child editable={this.props.editableOpts} />
      );
    } else {
      // In this case, Child will use the editableOpts from its own getDefaultProps()
      return (
        <Child />
      );
    }
  }
});

Чи є спосіб написати це без оператора if? Я думав щось подібне до типу вбудованого-якщо-висловлювання в JSX:

var parent = React.createClass({
  propTypes: {
    editable: React.PropTypes.bool.isRequired,
    editableOpts: React.PropTypes.shape({...})
  },
  render: function() {
    return (
      <Child 
        {this.props.editable ? editable={this.props.editableOpts} : null} 
      />
    );
  }
});

Для підведення підсумків : Я намагаюся знайти спосіб визначити опору Child, але передаю значення (або роблю щось інше), яке Childвсе одно витягує значення цього реквізиту з Childвласного getDefaultProps().


Чи можете ви також включити код Child? Крім того, ви мали намір сказати <Child editableOpts={this.props.editableOpts} />замість <Child editable={this.props.editableOpts} />?
Jim Skerritt

@JimSkerritt Я не плутав реквізит, хоча знаю, що це виглядає саме так. Я намагаюся використовувати, react-bootstrap-tableі це формат, який вони використовують. Я не впевнений, що Childкод насправді має значення для того, про що я запитую, саме тому я його не включив. Я насправді просто шукаю спосіб, як необов'язково передавати або не передавати опис Child, який не вимагає наявності величезної кількості подібного коду в if-statement в Parent.
Метью Гербст,

1
Боже, просто перевіряю :) Незабаром я отримаю для вас відповідь
Джим Скерритт

Відповіді:


151

Ви були близькі зі своєю ідеєю. Виявляється, передача undefinedдля реквізиту - це те саме, що взагалі не включати його, що все одно спричинить значення пропа за замовчуванням. Отже, ви можете зробити щось подібне:

var parent = React.createClass({
  propTypes: {
    editable: React.PropTypes.bool.isRequired,
    editableOpts: React.PropTypes.shape({...})
  },
  render: function() {
    return <Child 
      editable={this.props.editable ?
                  this.props.editableOpts : 
                  undefined}
    />;
  }
});

О, чудово! Ви знайшли це десь у документації? Я шукав це, але не знайшов нічого під час швидкого пошуку
Метью Гербст,

не впевнений, чи є це в документації чи ні, це просто те, про що я дізнався, використовуючи React :)
Джим Скерритт

10
nullне озброєний такою владою, як undefined, до речі.
Сезон

3
корисний фокус! хотів би, щоб були хороші ресурси про те, як ефективно використовувати методи умовної візуалізації
nicodjimenez

1
У falseвипадку, якщо це працює не так, як я хотів - я все одно отримую пару ключ-значення property:: null. Чи можливо це ще якось зробити з одним елементом JSX?
Галь Грюнфельд,

29

Додайте оператор поширення до this.props.editable:

<Child {...(this.props.editable ? {editable: {this.props.editableOpts}} : {})} >

повинен працювати.


1
Чи не дає це той самий результат, що і editable = {this.props.editable? this.props.editableOpts: undefined} Або є різниця?
garyee

1
@garyee: різниця полягає в тому, що деякі компоненти можуть неправильно трактуватися undefinedяк перевизначення (наприклад null, це завжди перевизначення), тому єдиний спосіб зберегти значення за замовчуванням замість того, щоб встановити його як хибне значення - це явно не передавати його, не передавати undefined.
Yann Dìnendal,

@ YannDìnendal, що якщо я використовую порожній об'єкт замість невизначеного, наприклад <Child {... (this.props.editable? {Editable: {this.props.editableOpts}}: {)}> Чи це має значення? який з них кращий?
sktguha

1
@sktguha: так, справді, схоже на друкарську помилку, я думаю: ми не можемо розповсюджувати невизначено, тому так, це повинно бути в {}кінці. Я запропоную видання, дякую :)
Янн Дінендал,

18

Визначте propsзмінну:

let props = {};
if (this.props.editable){
  props.editable = this.props.editable;
}

А потім використовуйте його в JSX:

<Child {...props} />

Ось рішення у вашому коді:

var parent = React.createClass({
  propTypes: {
    editable: React.PropTypes.bool.isRequired,
    editableOpts: React.PropTypes.shape({...})
  },
  render: function() {
    let props = {};
    if (this.props.editable){
      props.editable = this.props.editable;
    }
    return (
      <Child {...props} />
    );
  }
});

Джерело, документація React: https://facebook.github.io/react/docs/jsx-in-depth.html#spread-attributes


Мені подобається це рішення. Я б хотів childPropsуникнути плутанини
Даніель Рейна

4

Насправді, якщо ваш проп буде логічним, він не потрібен для реалізації умови, але якщо ви хочете додати проп за вбудованою умовою, вам слід написати, як показано нижче:

const { editable, editableOpts } = this.props;
return (
  <Child {...(editable && { editable: editableOpts } )} />
);

Сподіваюся, це вас не бентежить. що {...означає це поширення оператор як пропливають існував реквізит: {...props}і editable &&кошти , якщо editableце об'єкт буде робити і ми зробимо новий об'єкт , як він: що це значить , але якщо це правда.true{ editable: editableOpts }{...{...{ editable: editableOpts }}editable={editableOpts}this.porps.editable


0
var parent = React.createClass({
  propTypes: {
    editable: React.PropTypes.bool.isRequired,
    editableOpts: React.PropTypes.shape({...})
  },
  render: function() {
    return (
      <Child 
        {...(this.props.editable && {editable=this.props.editableOpts})} 
      />
    );
  }
});

Це передає реквізит, якщо він визначений. В іншому випадку реквізит не передається. В інших відповідях реквізит все ще передається, але значення, undefinedяке все ще означає, що реквізит передається.


1
Перехід undefinedдо реквізиту рівнозначно не передачі його взагалі.
Метью Гербст

Так я розумію. Я просто хотів, щоб це було зрозуміло! Дякую!
sanair96

0

також ви можете спробувати цей короткий ручний спосіб

 <Child {...(this.props.editable  && { editable: this.props.editableOpts })} />
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.