![](/img/trans.png)
[英]How do I conditionally render react functional components with switch statement?
[英]How do I conditionally add attributes to React components?
如果满足特定条件,有没有办法只向 React 组件添加属性?
我应该在渲染后基于 Ajax 调用向表单元素添加 required 和 readOnly 属性,但我看不出如何解决这个问题,因为readOnly="false"
与完全省略该属性不同。
下面的示例应该解释我想要什么,但它不起作用。
(解析错误:意外的标识符)
function MyInput({isRequired}) {
return <input classname="foo" {isRequired ? "required" : ""} />
}
显然,对于某些属性,如果传递给它的值不真实,React 足够智能以省略该属性。 例如:
const InputComponent = function() {
const required = true;
const disabled = false;
return (
<input type="text" disabled={disabled} required={required} />
);
}
将导致:
<input type="text" required>
更新:如果有人对如何/为什么发生这种情况感到好奇,您可以在 ReactDOM 的源代码中找到详细信息,特别是在DOMProperty.js文件的第30和167行。
juandemarco 的回答通常是正确的,但这是另一种选择。
以您喜欢的方式构建对象:
var inputProps = {
value: 'foo',
onChange: this.handleChange
};
if (condition)
inputProps.disabled = true;
渲染传播,也可以选择传递其他道具。
<input
value="this is overridden by inputProps"
{...inputProps}
onChange={overridesInputProps}
/>
以下是通过React-Bootstrap (0.32.4 版)使用BootstrapButton
的示例:
var condition = true;
return (
<Button {...(condition ? {bsStyle: 'success'} : {})} />
);
根据条件,将返回{bsStyle: 'success'}
或{}
。 然后,扩展运算符会将返回对象的属性扩展到Button
组件。 在 falsy 情况下,由于返回的对象上不存在任何属性,因此不会将任何内容传递给组件。
基于Andy Polhill 评论的另一种方式:
var condition = true;
return (
<Button bsStyle={condition ? 'success' : undefined} />
);
唯一的小区别是,在第二个示例中,内部组件<Button/>
的props
对象将有一个键bsStyle
,其值为undefined
。
这是一个替代方案。
var condition = true;
var props = {
value: 'foo',
...( condition && { disabled: true } )
};
var component = <div { ...props } />;
或者它的内联版本
var condition = true;
var component = (
<div
value="foo"
{ ...( condition && { disabled: true } ) } />
);
这是我的一种方法。
有条件的:
<Label
{...{
text: label,
type,
...(tooltip && { tooltip }),
isRequired: required
}}
/>
我仍然更喜欢使用传递 props 的常规方式,因为它在没有任何条件的情况下更具可读性(在我看来)。
没有条件:
<Label text={label} type={type} tooltip={tooltip} isRequired={required} />
假设我们想在条件为真时添加一个自定义属性(使用 aria-* 或 data-*):
{...this.props.isTrue && {'aria-name' : 'something here'}}
假设我们想在条件为真时添加一个样式属性:
{...this.props.isTrue && {style : {color: 'red'}}}
您可以使用相同的快捷方式,用于添加/删除(部分)组件( {isVisible && <SomeComponent />}
)。
class MyComponent extends React.Component {
render() {
return (
<div someAttribute={someCondition && someValue} />
);
}
}
如果你使用 ECMAScript 6,你可以简单地这样写。
// First, create a wrap object.
const wrap = {
[variableName]: true
}
// Then, use it
<SomeComponent {...{wrap}} />
这应该可以工作,因为在 Ajax 调用之后您的状态将发生变化,并且父组件将重新呈现。
render : function () {
var item;
if (this.state.isRequired) {
item = <MyOwnInput attribute={'whatever'} />
} else {
item = <MyOwnInput />
}
return (
<div>
{item}
</div>
);
}
在 React 中,你可以有条件地渲染组件,也可以渲染它们的属性,比如 props、className、id 等等。
在 React 中,使用三元运算符是一个很好的实践,它可以帮助您有条件地渲染组件。
一个示例还展示了如何有条件地呈现 Component 及其样式属性。
这是一个简单的例子:
class App extends React.Component { state = { isTrue: true }; render() { return ( <div> {this.state.isTrue ? ( <button style={{ color: this.state.isTrue ? "red" : "blue" }}> I am rendered if TRUE </button> ) : ( <button>I am rendered if FALSE</button> )} </div> ); } } ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="root"></div>
例如使用自定义容器的属性样式
const DriverSelector = props => {
const Container = props.container;
const otherProps = {
...( props.containerStyles && { style: props.containerStyles } )
};
return (
<Container {...otherProps} >
在我看来,管理多个条件道具的最佳方法是来自@brigand 的道具对象方法。 但是可以改进以避免为每个条件道具添加一个if
块。
随意重命名(iv、condVal、cv、_、...)
如果满足条件,您可以定义一个辅助函数来返回一个值或另一个值:
// components-helpers.js
export const ifVal = (cond, trueValue=true, falseValue=null) => {
return cond ? trueValue : falseValue
}
如果cond
为true
(或truthy ),则返回trueValue
- 或true
。 如果cond
为false
(或falsy ),则返回falseValue
- 或null
。
这些默认值( true
和null
)通常是允许将 prop 传递或不传递给 React 组件的正确值。 您可以将此函数视为“改进的 React 三元运算符”。 如果您需要更多地控制返回值,请改进它。
让我们将它与许多道具一起使用。
// your-code.js
import { ifVal } from './components-helpers.js'
// BE SURE to replace all true/false with a real condition in you code
// this is just an example
const inputProps = {
value: 'foo',
enabled: ifVal(true), // true
noProp: ifVal(false), // null - ignored by React
aProp: ifVal(true, 'my value'), // 'my value'
bProp: ifVal(false, 'the true text', 'the false text') // 'my false value',
onAction: ifVal(isGuest, handleGuest, handleUser) // it depends on isGuest value
};
<MyComponent {...inputProps} />
这种方法类似于使用classnames 实用程序有条件地管理类的流行方法,但适用于 props。
即使有许多条件道具,您也将拥有清晰易读的语法:每个新道具只需在对象声明中添加一行代码。
通过这种方式,您可以用简单的函数调用替换重复运算符( ...
、 &&
、 ? :
、...)的语法噪音,当您有许多道具时,这可能会非常烦人。
作为开发人员,我们的首要任务是编写解决问题的最明显的代码。 太多次我们为自我解决问题,在不需要的地方增加了复杂性。 我们的代码应该是直截了当的,对今天的我们、明天的我们和我们的伙伴来说。
仅仅因为我们可以做某事并不意味着我们应该
我希望这个迟到的回复会有所帮助。
使用undefined
适用于大多数属性:
const name = "someName";
return (
<input name={name ? name : undefined} />
);
<input checked={true} type="checkbox" />
<Button {...(isWeb3Enabled ? {} : { isExternal: true })}>
Metamask
</Button>
考虑帖子JSX In Depth ,您可以通过以下方式解决您的问题:
if (isRequired) {
return (
<MyOwnInput name="test" required='required' />
);
}
return (
<MyOwnInput name="test" />
);
我认为这对于那些希望属性的值是一个函数的人可能很有用:
import { RNCamera } from 'react-native-camera';
[...]
export default class MyView extends React.Component {
_myFunction = (myObject) => {
console.log(myObject.type); //
}
render() {
var scannerProps = Platform.OS === 'ios' ?
{
onBarCodeRead : this._myFunction
}
:
{
// here you can add attribute(s) for other platforms
}
return (
// it is just a part of code for MyView's layout
<RNCamera
ref={ref => { this.camera = ref; }}
style={{ flex: 1, justifyContent: 'flex-end', alignItems: 'center', }}
type={RNCamera.Constants.Type.back}
flashMode={RNCamera.Constants.FlashMode.on}
{...scannerProps}
/>
);
}
}
希望这个对你有帮助。 您可以使用三元运算符和布尔值有条件地添加只读属性。 下面给出的是启用文本输入的 React 类组件的示例,前提是用户勾选了复选框输入。
class Input extends React.Component{
constructor(props){
super(props)
this.state={ checkbox: false}
this.handleCheckbox=this.handleCheckbox.bind(this);
}
handleCheckbox(){
this.setState({checkbox: true})
}
render(){
const{checkbox}=this.state;
return (
<div>
<input onChange={this.handleCheckbox} type="checkbox" />
<label htmlFor="pets">Do you have pets? If Yes,
please tick mark & enter their names below and provide at least two
names.</label>
<div>
<input type="text" disabled={!checkbox ?true : false} required={true}/>
<input type="text" disabled={!checkbox ?true : false} required={true}/>
<input type="text" disabled={!checkbox ?true : false} required={false}/>
</div>
</div>
);
}
}
这将在 DOM 中进行更改。 此外,您可以为文本类型输入创建一个单独的子组件,并将复选框输入的状态传递给它。
在 React 中,我们将值作为道具从父组件传递给子组件。 如果值为 false,则不会将其作为 props 传递。 同样在某些情况下,我们也可以使用三元(条件运算符)。
以简单的方式
const InputText= (required = false , disabled = false) =>
(<input type="text" disabled={disabled} required={required} />);
并像那样使用它,如果您希望它是真实的
<InputText required disabled/>
<input disabled={disabled} />
// renders either `<input>` or `<input disabled>`
<div aria-selected= {selected ? "" : undefined} />
// renders either `<div aria-selected></div>` or `<div></div>`
[1]布尔属性列表: https : //github.com/facebook/react/blob/3f9480f0f5ceb5a32a3751066f0b8e9eae5f1b10/packages/react-dom/src/shared/DOMProperty.js#L318-L345
function MyInput({isRequired}) {
return <input classname="foo" {...(isRequired && { required: true })} />
}
以一种简单的方式
const InputText= ({required = false , disabled = false, ...props}) =>
(<input type="text" disabled={disabled} required={required} {...props} />);
并像这样使用它
<InputText required disabled/>
在反应功能组件中,您可以尝试这样的事情来省略不必要的标签属性。
<div className="something" ref={someCondition ? dummyRef : null} />
如果我需要省略 ref、class 等标签,这对我有用。但我不知道这是否适用于每个标签属性
给定一个局部变量isRequired
我相信您可以在您的渲染方法(如果使用类)或返回语句(如果使用 function 组件)中执行以下操作:
<MyComponent required={isRequired ? 'true' : undefined} />
此外,您可以对Boolean
进行其他值
const MyComponent = function() {
const Required = "yes";
return (
<input
required={Required === "yes"}
type="text"
key={qs.Name}
name="DefaultValue"
label={qs.QuestionTitle}
onChange={(event) => handleInputChange(index, event)}
placeholder={qs.QuestionTitle}
/>
);
}
如果是针对有限数量的属性,这将是可行的
function MyInput({isRequired}) {
if (isRequired) {
return <input classname="foo" isRequired={isRequired} />
}
return <input classname="foo" />
}
如果您有大量属性,则很难为每个属性编写 if else 条件并相应地返回。 为此,您可以将这些属性推送到 object 中,并在返回的元素中使用扩展运算符。
function MyInput({ prop1, prop2, ...propN }) {
const props = {};
if (prop1) props.prop1 = prop1;
.
.
.
if (propN) props.propN = propN;
return <input classname="foo" {...props} />
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.