How do I conditionally add attributes to React com

2020-01-25 03:28发布

Is there a way to only add attributes to a React component if a certain condition is met?

I'm supposed to add required and readOnly attributes to form elements based on an Ajax call after render, but I can't see how to solve this since readOnly="false" is not the same as omitting the attribute completely.

The example below should explain what I want, but it won't work (Parse Error: Unexpected identifier).

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

11条回答
闹够了就滚
2楼-- · 2020-01-25 03:43

Apparently, for certain attributes, React is intelligent enough to omit the attribute if the value you pass to it is not truthy. For example:

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

        return (
            <input type="text" disabled={disabled} required={required} />
        );
    }
});

will result in:

<input type="text" required>

Update: if anyone is curious as to how/why this happens, you can find details in ReactDOM's source code, specifically at lines 30 and 167 of the DOMProperty.js file.

查看更多
仙女界的扛把子
3楼-- · 2020-01-25 03:45

Here's a way I do it.

with Conditional:

<Label
    {...{
      text: label,
      type,
      ...(tooltip && { tooltip }),
      isRequired: required
    }}
/>

I still prefer using the regular way of passing props down because it is more readable (in my opinion) in the case of not have any conditionals.

with No conditional:

<Label text={label} type={type} tooltip={tooltip} isRequired={required} />
查看更多
可以哭但决不认输i
4楼-- · 2020-01-25 03:46

Here is an example of using Bootstrap's Button via React-Bootstrap (version: 0.32.4).

var condition = true;

return (
  <Button {...(condition ? {bsStyle: 'success'} : {})} />
);

Depending on the condition, either {bsStyle: 'success'} or {} will be returned. The spread operator will then spread the properties of the returned object to Button component. In the falsy case, since no properties exist on the returned object, nothing will be passed to the component.


Alternative way based on @Andy Polhill's comment below:

var condition = true;

return (
  <Button bsStyle={condition ? 'success' : undefined} />
);

The only small difference is that in the 2nd example inner component <Button/>'s props object will have a key bsStyle with value of undefined.

查看更多
Juvenile、少年°
5楼-- · 2020-01-25 03:47

Just throwing another option out there, but @juandemarco's answer is usually correct.

Build an object how you like:

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

if (condition) inputProps.disabled = true;

Render with spread, optionally passing other props also.

<input 
    value="this is overridden by inputProps" 
    {...inputProps} 
    onChange={overridesInputProps}
 />
查看更多
闹够了就滚
6楼-- · 2020-01-25 03:50

Late to the party.

Lets say we want to add a custom property (using aria-* or data-*) if a condition is true:

{...this.props.isTrue && {'aria-name' : 'something here'}}

Lets say we want to add a style property if a condition is true:

{...this.props.isTrue && {style : {color: 'red'}}}
查看更多
登录 后发表回答