[英]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}
/>;
}
});
將擴展運算符添加到this.props.editable
:
<Child {...(this.props.editable ? {editable: this.props.editableOpts} : {})} >
應該管用。
定義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
實際上,如果您的道具是布爾值,則不需要實現條件,但如果您想通過內聯條件添加道具,您應該編寫如下:
const { editable, editableOpts } = this.props;
return (
<Child {...(editable && { editable: editableOpts } )} />
);
希望它不會讓你感到困惑。 {...
表示它是傳播運算符,就像傳遞現有的 props: {...props}
和editable &&
表示如果editable
為true
,則{ 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}
/>
);
}
});
有條件的我們可以通過這樣的道具
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
,這仍然意味着道具正在被傳遞。
嘿,我可能會遲到,但我想分享一個小提示。 如果您在這里是因為您想動態傳遞道具。 然后您可以使用 * 符號將所有東西作為別名導入,即在這種情況下為 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>
這可能會對您有所幫助。 我經常使用這種方法
<Component
otherProps
{...(yourCondition ? {
deleteIcon: <DeleteIcon id={`${id}_icon`} />,
}
: {})}
/>
我的做法是用想要的道具或空的 object 構建一個 object,然后將其傳播到孩子身上。 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="..."
/>;
這樣,如果 prop 是 undefined 或 falsey,一個空的 object 將被傳播到 child = onChange 將不會被傳遞。 兩者都有效:
<EnhancedField name="vanilla" />
<EnhancedField name="enhanced" onChange={changeHandler} />
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.