反应:内联有条件地将道具传递给组件

Posted

技术标签:

【中文标题】反应:内联有条件地将道具传递给组件【英文标题】:React: inline conditionally pass prop to component 【发布时间】:2015-11-20 20:22:49 【问题描述】:

我想知道是否有比使用 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 中的一种 inline-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 仍然拉prop 的值来自Child 自己的getDefaultProps()

【问题讨论】:

你能把Child的代码也包括进来吗?另外,你的意思是说&lt;Child editableOpts=this.props.editableOpts /&gt; 而不是&lt;Child editable=this.props.editableOpts /&gt; @JimSkerritt 我没有混淆道具,尽管我知道它看起来是那样的。我正在尝试使用react-bootstrap-table,这就是他们使用的格式。我不确定Child 代码对我所要求的内容是否真的很重要,这就是我没有包含它的原因。我真的只是在寻找一种方法来选择性地将道具传递或不传递给Child,这不需要在Parent 的if 语句中包含大量类似的代码。 【参考方案1】:

你的想法很接近。事实证明,为一个 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
    />;
  
);

【讨论】:

哦,太棒了!您是否在某处的文档中找到了它?我一直在寻找它,但在快速搜索过程中找不到任何东西 null 没有像undefined 这样的力量,顺便说一句。 实用技巧!希望有关于如何有效使用条件渲染技术的好资源 false 的情况下,它不能按我想要的方式工作——我仍然得到一个键值对:property:null。是否仍然可以使用单个 JSX 元素以某种方式做到这一点? 我知道这个答案已经很老了,所以我不知道在此期间情况是否发生了变化,但对于任何在 2021 年偶然发现这个答案的人:传递 undefined 作为道具是 与根本不设置道具不同。在一个组件中,检查Object.keys(props) 将显示已设置的属性——甚至是undefined 的值。这对于某些组件很重要,这些组件根据设置的 props 作为受控和非受控组件。【参考方案2】:

this.props.editable 中添加扩展运算符:

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

应该可以。

【讨论】:

这不会产生与 editable= this.props.editable 相同的结果吗? this.props.editableOpts : undefined 还是有区别? @garyee:不同之处在于某些组件可能会错误地将undefined 视为覆盖(例如null,它始终是覆盖),因此保留默认值而不是设置的唯一方法它到一个虚假的值是明确不传递它,不传递undefined @YannDìnendal 如果我使用空对象而不是未定义对象会怎样,例如 有什么不同吗?哪个更好? @sktguha :是的,确实,我认为这看起来像是一个错字:我们不能传播未定义的,所以是的,它应该是一个 最后。我会建议一个版本,谢谢:)【参考方案3】:

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

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

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

希望它不会让您感到困惑。 ... 表示它是像传递现有道具一样的传播运算符:...propseditable &amp;&amp; 表示如果 editabletrue editable: editableOpts 对象将生成,... 我们将生成一个新对象,如它:... editable: editableOpts 表示editable=editableOpts 但如果this.porps.editable 为真。

【讨论】:

【参考方案5】:

嘿,我可能会迟到,但我想分享一个小提示。 如果您在这里是因为您想动态传递道具。然后你可以使用 * 符号将所有东西作为别名导入,即在这种情况下作为 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>

【讨论】:

【参考方案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,这仍然意味着道具正在被传递。

【讨论】:

undefined 传递给一个prop 相当于根本不传递它。 @MatthewHerbst 这不是真的。通过undefined 和根本不通过是不一样的。 @pishpish 确实如此。试试看。 天哪,我以为这是一个 Angular 线程。对不起。 @MatthewHerbst 我的错。我错觉传递 undefined 就等于传递 props。【参考方案7】:

你也可以试试这个速记方法

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

【讨论】:

以上是关于反应:内联有条件地将道具传递给组件的主要内容,如果未能解决你的问题,请参考以下文章

如何使用反应路由器将道具传递给非子组件?

将道具传递给动态反应组件

反应不将道具传递给组件

传递给子组件时道具未定义(反应钩子)

在反应中使用css模块如何将className作为道具传递给组件

在页面加载时将道具传递给子组件 - 与 next.js 做出反应