React:内联有条件地将 prop 传递给组件

React: inline conditionally pass prop to component

我想知道是否有比使用 if 语句更好的有条件地传递 prop 的方法。

例如,现在我有:

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 中的一种内联 if 语句:

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().

中提取该道具的价值

您的想法很接近。事实证明,为 prop 传递 undefined 与根本不包含它是一样的,这仍然会触发默认的 prop 值。所以你可以这样做:

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

定义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

this.props.editable 添加展开运算符:

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

应该可以。

实际上,如果你的 prop 是布尔值,则不需要实现条件,但如果你想通过内联条件添加 prop,你应该像下面这样写:

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

希望它不会让您感到困惑。 {... 表示它是传播运算符,就像传递现有道具一样:{...props}editable && 表示如果 editabletrue,则 { editable: editableOpts } 对象将使用 {... 我们将创建一个类似的新对象:{...{ editable: editableOpts }} 表示 editable={editableOpts} 但如果 this.porps.editable 为真。

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 这仍然意味着道具正在被传递。

你也可以试试这个简写方式

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

嘿,我可能来晚了,但我想分享一个小技巧。 如果你来这里是因为你想动态传递道具。然后你可以使用 * 符号将所有东西作为别名导入,即在这种情况下作为 grs 然后导入将在一个对象中,然后你可以使用该对象动态传递道具。 希望这对你们中的一些人有所帮助。

import * as grs from "../components/Theme";
import React from "react";
const GridInput = ({ sp, ...props }) => {
  return (
    <Grid {...grs[`gr${sp}`]}>
      <Input {...props} />
    </Grid>
  );
};
export default GridInput;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>