React: inline conditionally pass prop to component

2019-01-17 10:11发布

问题:

I would like to know if there is a better way to conditionally pass a prop than using an if-statement.

For example, right now I have:

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

Is there a way to write this without the if-statement? I am was thinking something along the lines of a type of inline-if-statement in the 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} 
      />
    );
  }
});

To wrap-up: I'm trying to find a way to define a prop for Child, but pass a value (or do something else) such that Child still pulls that prop's value from Child's own getDefaultProps().

回答1:

You were close with your idea. It turns out that passing undefined for a prop is the same as not including it at all, which will still trigger the default prop value. So you could do something like this:

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:

Define props variable:

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

And then use it in JSX:

<Child {...props} />

Here is a solution in your code:

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

Source, React documentation: https://facebook.github.io/react/docs/jsx-in-depth.html#spread-attributes



回答3:

Add a spread operator to the this.props.editable:

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

should works.



回答4:

Actually, if your prop is boolean it isn't needed to implement condition but if you wanna add prop by inline condition you should write like below:

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

Hope it doesn't confuse you. the {... means it is spread operator like passing existed props: {...props} and the editable && means if editable is true the { editable: editableOpts } object will make and with {... we will make a new object like it: {...{ editable: editableOpts }} that it means editable={editableOpts} but if this.porps.editable is true.



回答5:

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