如何有条件地添加属性以响应 DOM 元素

IT技术 javascript reactjs attributes conditional react-jsx
2021-05-26 00:15:18

我有一个场景,我使用 React.js 使用以下代码创建一个 div:

React.createElement('div', {}, "div content") 

一些额外的 javascript 处理将允许我之后推断这个 div 是否需要将 className 属性设置为“ClassA”或“ClassB”,或者它根本不应该有 className。

javascript 中有没有办法访问从 React DOM 创建的 div 并将 className 属性添加到其中?

注意:我无法实现这是 JSX,所以我求助于 createElement 方法。

编辑:值得一提的是,我可能需要有条件地添加 className 以外的属性。例如,我可能需要根据条件逻辑向锚标记添加或不添加“alt”属性。先感谢您。

4个回答

使用JSX 传播使用 props 构建和对象,根据需要修改它并将其传递给组件,如下所示:

const props = {
    name: 'SomeName'
}

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

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

看到那个...语法了吗?该扩展运算符完成了这项工作 - 所有props最终都将作为您组件上的单独属性。

看看这个 plunk:http : //www.webpackbin.com/4JzKuJ9C-

因为您最初试图在 JSX 中拥有您的逻辑。我有一个使用状态的 jsx 解决方案

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>

该示例显示了如何使用 state 类似地更改 className,您可以设置您想要更改的任何属性。

您可以使用 ES6 语法来实现所需的功能

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

return <YourComponent {...yourComponentProps} />

这在 React 中是很正常的情况,几乎不需要特殊处理。

注意:最好以声明方式传递组件树,但如果这不是一个选项,您可以绑定侦听器函数componentDidMount并取消绑定它们,componentWillUnmount如下例所示。只要他们调用 setState,你的组件的渲染函数就会被触发。

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>

PS - 避免使用componentWillMount,它会导致生命周期中的错误,并且有传言说它可能会在 React 的未来版本中被删除。始终在内部发出异步副作用负载请求componentDidMount并在componentWillUnmount. 即使你没有什么可渲染的,你最好在数据到达之前渲染一个占位符组件(快速加载的最佳选择),或者什么都不渲染。