Реагировать: inline условно передать опору компоненту

Я хотел бы знать, есть ли лучший способ условно передать реквизит, чем использование оператора 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? Я думал о чем-то вроде встроенного оператора 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().

Ответы

Ответ 1

Вы были близки своей идее. Оказывается, что прохождение 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}
    />;
  }
});

Ответ 2

Определите переменную 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.

Ответ 3

Добавьте оператор распространения к this.props.editable:

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

должно работать.

Ответ 4

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

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

Надеюсь, это вас не смущает. {... означает, что это оператор распространения, как передача существующих реквизитов: {...props} а editable && означает, что если editable true объект { editable: editableOpts } создаст и с помощью {... мы создадим новый объект вроде этого: {...{ editable: editableOpts }} что означает editable={editableOpts} но если this.porps.editable имеет значение true.

Ответ 5

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

Условно мы можем передать реквизит, как это

Ответ 6

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 означает, что реквизиты проходят.

Ответ 7

const CleaningItem = ({ disabled = false }) => (
 <View
     style={[styles.container, disabled && styles.disabled]}
     pointerEvents={disabled ? 'none' : 'auto'}
 >
     <Button
         disabled={disabled || null}
         title="SELECT"
     />
 </View>
);