如何有条件地向React组件添加属性?

Rem*_*ure 453 javascript reactjs

有没有办法只在满足某个条件时才向React组件添加属性?

我应该在渲染之后添加必需和readOnly属性以基于ajax调用来形成元素,但是我无法看到如何解决这个问题,因为readOnly ="false"与完全省略属性不同.

下面的例子应该解释我想要什么,但不会工作(解析错误:意外的标识符).

var React = require('React');

var MyOwnInput = React.createClass({
    render: function () {
        return (
            <div>
                <input type="text" onChange={this.changeValue} value={this.getValue()} name={this.props.name}/>
            </div>
        );
    }
});

module.exports = React.createClass({
    getInitialState: function () {
        return {
            isRequired: false
        }
    },
    componentDidMount: function () {
        this.setState({
            isRequired: true
        });
    },
    render: function () {
        var isRequired = this.state.isRequired;

        return (
            <MyOwnInput name="test" {isRequired ? "required" : ""} />
        );
    }
});
Run Code Online (Sandbox Code Playgroud)

jua*_*rco 462

显然,对于某些属性,React足够智能,如果传递给它的值不是真的,则省略该属性.例如:

var InputComponent = React.createClass({
    render: function() {
        var required = true;
        var disabled = false;

        return (
            <input type="text" disabled={disabled} required={required} />
        );
    }
});
Run Code Online (Sandbox Code Playgroud)

将导致:

<input type="text" required>
Run Code Online (Sandbox Code Playgroud)

  • 一般来说,"null"意味着"就像我根本没有指定它".对于布尔dom属性,true/false优先于重复属性name/false,例如`<input disabled>`编译为`React.createElement('input',{disabled:true})` (37认同)
  • "readonly"永远不会被添加,因为React期望属性"readOnly"(带有大写字母O). (7认同)
  • 谢谢!确保该值不仅仅是空字符串或零,这些可能不会被删除.例如,您可以传递这样的值,并且如果它的计算结果为false,则应确保将其删除:`alt = {props.alt || 空}`. (7认同)
  • 谢谢,@杰克.我曾尝试将属性设置为`false`,但只有`null`确保该属性实际被删除. (4认同)
  • 我收到“警告:收到非布尔属性“active”的“false”...” (3认同)

Bri*_*and 340

只是抛出另一个选项,但@ juandemarco的回答通常是正确的.

根据自己的喜好构建对象:

var inputProps = {
  value: 'foo',
  onChange: this.handleChange
};

if (condition) inputProps.disabled = true;
Run Code Online (Sandbox Code Playgroud)

使用传播渲染,也可以选择传递其他道具.

<input 
    value="this is overridden by inputProps" 
    {...inputProps} 
    onChange={overridesInputProps}
 />
Run Code Online (Sandbox Code Playgroud)

  • 这实际上非常有用,特别是在有条件地添加许多属性时(我个人不知道它可以这样做). (11认同)

Arm*_*yan 251

下面是使用的示例自举Button经由阵营-引导.

var condition = true;

return (
  <Button {...(condition ? {bsStyle: 'success'} : {})} />
);
Run Code Online (Sandbox Code Playgroud)

根据具体情况,将返回{bsStyle: 'success'}{}将返回.然后,扩展运算符将返回对象的属性扩展到Button组件.在虚假的情况下,由于返回的对象上不存在任何属性,因此不会将任何内容传递给组件.


基于@Andy Polhill的评论的替代方式如下:

var condition = true;

return (
  <Button bsStyle={condition ? 'success' : undefined} />
);
Run Code Online (Sandbox Code Playgroud)

唯一的小区别是,在第二个示例中,内部组件<Button/>props对象将具有bsStyle值为的键undefined.

  • @Punit,扩展运算符的优先级低于条件运算符,因此首先计算条件,(从它得到`{bsStyle:'success'}'或`{}`),然后传播该对象. (5认同)
  • 下面会做同样的`<Button bsStyle = {condition?'success':undefined} />`我发现语法稍微容易一点,传递`undefined`会省略属性. (4认同)
  • 这是唯一允许单选按钮不会对未设置“onChange”的“checked”值发出警告的解决方案(即使“checked”设置为 false)。所以 `{...(checked ? {checked} : {})}`。感谢您的解决方案! (4认同)
  • @AndyPolhill看起来对我很好,并且更容易阅读代码,唯一的小区别是在你的代码示例中,内部组件`<Button />`的`props`对象将有一个键'bsStyle`,其值为`undefined `. (3认同)
  • 解决了我的问题!谢谢。下面是我如何使用它的示例,有条件地传播 React Native 样式类: `style={{...(isReadOnly ? styles.readOnly : {}), ...styles.baseStyle }}` 然后,在组件内部,您可以将其混合到组件使用的任何样式中:`&lt;Text style={...props.style, ...localStyleClass} &gt;Hello World&lt;Text&gt;` (3认同)

Sea*_*son 70

迟到了.这是另一种选择.

var condition = true;

var props = {
  value: 'foo',
  ...( condition && { disabled: true } )
};

var component = <div { ...props } />;
Run Code Online (Sandbox Code Playgroud)

或者它的内联版本

var condition = true;

var component = (
  <div
    value="foo"
    { ...( condition && { disabled: true } ) } />
);
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这种方法,它让我的同事很酷.开玩笑,从它的外观来看,道具毕竟只是作为一个键值对传递,这是正确的吗? (8认同)
  • 如果“condition”为 false,这将尝试扩展/迭代 false,我认为这是不正确的。 (3认同)
  • @LarsNyström,这是有道理的。展开运算符仅接受可迭代对象,其中“false”不是一个。只需与 Babel 确认即可。当“condition”评估为 false 时,这适用于 Babel 实现运算符的方式。虽然一个简单的解决方法可能是“...(条件?{disabled:true}:{})”,但它会变得有点冗长。感谢您的宝贵意见! (3认同)

Ton*_*yen 16

这是我做的一种方式.

有条件的:

<Label
    {...{
      text: label,
      type,
      ...(tooltip && { tooltip }),
      isRequired: required
    }}
/>
Run Code Online (Sandbox Code Playgroud)

我仍然喜欢使用常规方式传递道具,因为在没有任何条件的情况下,它更具可读性(在我看来).

无条件:

<Label text={label} type={type} tooltip={tooltip} isRequired={required} />
Run Code Online (Sandbox Code Playgroud)


Gij*_*anB 14

您可以使用相同的快捷方式,用于添加/删除(部分)组件({isVisible && <SomeComponent />}).

class MyComponent extends React.Component {
  render() {
    return (
      <div someAttribute={someCondition && someValue} />
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果`someCondition`为真,但`someValue`是假的(例如`false`本身,或者`0`等),该属性是否仍然被包括在内?如果需要明确包含假值,例如坐标属性的"0"等,这很重要. (3认同)

Min*_*uke 12

迟到了.

假设我们想要在条件为真时添加自定义属性(使用aria-*或data-*):

{...this.props.isTrue && {'aria-name' : 'something here'}}
Run Code Online (Sandbox Code Playgroud)

假设我们想要在条件为真时添加样式属性:

{...this.props.isTrue && {style : {color: 'red'}}}
Run Code Online (Sandbox Code Playgroud)


Tim*_*Tim 12

undefined对大多数属性使用作品:

const name = "someName";

return (
    <input name={name ? name : undefined} />
);
Run Code Online (Sandbox Code Playgroud)


sny*_*nyh 7

如果你使用es6,你可以这样写.

// first, create a wrap object.
const wrap = {
    [variableName]: true
}
// then, use it
<SomeComponent {...{wrap}} />
Run Code Online (Sandbox Code Playgroud)


Nei*_*rdi 7

给定一个局部变量,isRequired您可以在渲染方法(如果使用类)或 return 语句(如果使用函数组件)中执行以下操作:

 <MyComponent required={isRequired ? 'true' : undefined} />
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如果 isRequired 未定义、 false 或 null (这与添加属性但将其设置为 不同),则不会添加该属性。'false'注意,我使用字符串而不是布尔值,以避免出现警告消息来自react(在非布尔属性上收到的布尔值)。


Mic*_*ker 5

这应该起作用,因为在ajax调用之后您的状态将改变,并且父组件将重新呈现。

render : function () {
    var item;
    if (this.state.isRequired) {
        item = <MyOwnInput attribute={'whatever'} />
    } else {
        item = <MyOwnInput />
    }
    return (
        <div>
            {item}
        </div>    
    );
}
Run Code Online (Sandbox Code Playgroud)