简体   繁体   English

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

[英]React: inline conditionally pass prop to component

I would like to know if there is a better way to conditionally pass a prop than using an if-statement.我想知道是否有比使用 if 语句更好的有条件地传递 prop 的方法。

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?有没有办法不用 if 语句来写这个? I am was thinking something along the lines of a type of inline-if-statement in the JSX:我正在考虑 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} 
      />
    );
  }
});

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() .总结:我试图找到一种方法来为Child定义一个道具,但传递一个值(或做其他事情)使得Child仍然从Child自己的getDefaultProps()中提取该道具的值。

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.事实证明,为 prop 传递undefined与根本不包含它是一样的,这仍然会触发默认的 prop 值。 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}
    />;
  }
});

Add a spread operator to the this.props.editable :将扩展运算符添加到this.props.editable

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

should work.应该管用。

Define props variable:定义props变量:

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

And then use it in JSX:然后在 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来源,React 文档: https ://facebook.github.io/react/docs/jsx-in-depth.html#spread-attributes

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. {...表示它是传播运算符,就像传递现有的 props: {...props}editable &&表示如果editabletrue ,则{ editable: editableOpts }对象将生成并且使用{...我们将创建一个新的object like it: {...{ editable: editableOpts }}这意味着editable={editableOpts}但如果this.porps.editable为真。

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

 <Child {...(this.props.editable  && { editable: this.props.editableOpts })} />
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}
      />
    );
  }
});

Conditionally we can pass props like this 有条件的我们可以通过这样的道具

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

This passes the props if they are defined.如果定义了道具,这将传递道具。 Else the props are not passed.否则道具不通过。 In the other answer's the props are still passed but the value is undefined which still means the props are being passed.在另一个答案中,道具仍然被传递,但值undefined ,这仍然意味着道具正在被传递。

Hey I might be late to jump in but I want to share a small tip.嘿,我可能会迟到,但我想分享一个小提示。 In case you are here for the reason that you want to pass props dynamically.如果您在这里是因为您想动态传递道具。 Then you can use * sign to import all the stuff as an alias , ie in this case as grs then the imports will be in an object, then you can use that object to pass props dynamically.然后您可以使用 * 符号将所有东西作为别名导入,即在这种情况下为 grs 然后导入将在一个对象中,然后您可以使用该对象动态传递道具。 Hope this will help some of you.希望这会对你们中的一些人有所帮助。

 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>

This may help you.这可能会对您有所帮助。 I use this method often我经常使用这种方法

    <Component
      otherProps
      {...(yourCondition ? { 
        deleteIcon: <DeleteIcon id={`${id}_icon`} />,
       }
      : {})}
    />

My take is to build an object with the wanted prop OR an empty object, and then spread it onto the child.我的做法是用想要的道具或空的 object 构建一个 object,然后将其传播到孩子身上。 Just 1 line of extra code before the jsx. jsx 之前只有 1 行额外代码。


const EnhancedField = (props) => {

  // create an object with only the onChange prop defined if exists, or empty if not:
  const onChangeIfDefined = props.onChange ? { onChange: props.onChange } : {};
  
  return <Field
           {...onChangeIfDefined}
           name="..."
         />;

This way, if the prop is undefined or falsey, an empty object will be spread onto the child = onChange will not be passed.这样,如果 prop 是 undefined 或 falsey,一个空的 object 将被传播到 child = onChange 将不会被传递。 Both will work:两者都有效:

<EnhancedField name="vanilla" />
<EnhancedField name="enhanced" onChange={changeHandler} />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM