How to conditionally add attributes to react DOM element

瘦欲@ 提交于 2019-12-05 11:11:36

Use JSX spread. Build and object with props, modify it however you like and pass it to component like so:

const props = {
    name: 'SomeName'
}

if (true) {
    props.otherName = 'otherName';
}

return (
    <SomeComponent {...props}/>
);

See that ... syntax? That spread operator do the job - all props will end up as separate attributes on your component.

Take a look at this plunk: http://www.webpackbin.com/4JzKuJ9C-

Since you were trying to initially have your logic in JSX. I have a jsx solution that uses state

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      classValue: ''
    }
  }
  handleClick = () => {
    if(this.state.classValue == '') {
      this.setState({classValue : 'green'});
    }
    else if(this.state.classValue == 'green') {
      this.setState({classValue : 'blue'});
    }
    else {
       this.setState({classValue : 'green'});
    }
  }
  render() {
    return (
    <div>
      <div className={this.state.classValue}>Hello World</div>
      <button onClick={this.handleClick()}>Toggle</button>
    </div>
  )}
}

ReactDOM.render(<App/>, document.getElementById('app'));
.green {
  background-color: green;
}
.blue {
  background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script>
<div id="app"></div>

The example shows how can you change your className similarly using state you can set whatever attributes you like to change.

You can use ES6 syntax to achieve the desired functionality

const yourComponentProps = {
  [ifThisIsTrue ? 'useThisName' : 'useAnotherName']: 'yourDesiredValue',
};

return <YourComponent {...yourComponentProps} />

This is a quite normal situation in React and requires virtually no special handling.

Note: It is best to hand props down the component tree declaratively but if that is not an option you can bind listener functions in componentDidMount and unbind them in componentWillUnmount as shown in the following example. So long as they call setState, your component's render function will get triggered.

const { Component, cloneElement } = React

class Container extends Component {
  constructor(props) {
    super(props)
    this.state = { classNames: [ 'foo' ] }
    this.appendClassName = () => {
      const { classNames } = this.state
      this.setState({ classNames: [ ...classNames, `foo_${classNames.length}` ] })
    }
  }
  componentDidMount() {
    document.querySelector('button').addEventListener('click', this.appendClassName)
  }
  componentWillUnmount() {
    document.querySelector('button').removeEventListener('click', this.appendClassName)
  }
  render() {
    const { children } = this.props
    const { classNames } = this.state
    
    return <div className={classNames.join(' ')}>{children}</div>
  }
}


ReactDOM.render(<Container>I am content</Container>, document.getElementById('root'))
.foo {
  font-family: monospace;
  border: 1px solid rgb(100, 50, 50);
  font-size: 1rem;
  border-style: solid;
  border-width: 1px;
  width: 50vw;
  height: 50vh;
  margin: auto;
  display: flex;
  align-self: center;
  justify-content: center;
  align-items: center;
}

.foo.foo_1 {
  font-size: 1.5rem;
  background-color: rgb(200, 100, 200);
}

.foo.foo_2 {
  font-size: 2rem;
  border-radius: 3px 7px;
  background-color: rgb(180, 120, 200);
}

.foo.foo_3 {
  border-style: dashed;
  background-color: rgb(175, 130, 180);
}

.foo.foo_4 {
  border-width: 2px;
  background-color: rgb(160, 165, 170);
}

.foo.foo_5 {
  border-width: 1rem;
  background-color: rgb(150, 200, 150);
}
<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>
<button>Click me</button>
<div id="root"></div>

P.S. - Avoid using componentWillMount, it can lead to bugs in the lifecycle and there is talk that it may be removed in a future version of React. Always make async side-effect laden requests within componentDidMount and clean them up in componentWillUnmount. Even if you have nothing to render, you are best off rendering a placeholder component until your data arrives (best option for fast loading), or nothing at all.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!