如何有条件地向React DOM元素添加属性

7

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

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

一些额外的javascript处理将允许我推断出这个div是否需要设置className属性为" ClassA"或"ClassB",或者它根本不需要className属性。 在javascript中有没有一种方法可以访问从React DOM创建的div,并向其添加className属性? 注意:我无法在JSX中实现这一点,因此我转而使用createElement方法。 编辑:值得一提的是,我可能需要有条件地添加其他属性而不仅仅是className。例如,根据条件逻辑,我可能需要向锚标签添加“alt”属性或不添加。 谢谢您提前的帮助。

如果组件的生命周期中需要更改状态,则可以使用状态属性。类如何更改?是在事件发生时还是通过Props? - Jecoms
这个应该能满足你的需求。https://github.com/JedWatson/classnames - Panther
感谢您的评论。请查看编辑部分以获取更多详细信息。 - jojo
4个回答

7
使用JSX展开。构建一个带有props的对象,随意修改它并将其传递给组件,如下所示:
const props = {
    name: 'SomeName'
}

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

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

看到那个...语法了吗?那个展开运算符会起作用 - 所有的 props 都将成为组件上单独的属性。
看一下这个 plunk:http://www.webpackbin.com/4JzKuJ9C-

1
我的代码第一次没有运行成功,因为我认为“...”只是表示“在这里放置某些内容”,但后来我读到它是一个实际的运算符,我加上它之后,咻地一声,就完美运行了!谢谢。 - HoldOffHunger

0

由于您最初尝试在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>

这个例子展示了如何使用状态来改变className,你可以设置任何你想要改变的属性。


0

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

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

return <YourComponent {...yourComponentProps} />

-1

这在React中是一个非常普遍的情况,几乎不需要特殊处理。

注意:最好以声明方式向组件树传递props,但如果无法实现,则可以像以下示例中所示,在componentDidMount中绑定监听器函数,并在componentWillUnmount中解除绑定。只要它们调用setState,您的组件的render函数就会被触发。

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>

附言 - 避免使用componentWillMount,它可能会导致生命周期中的错误,并且有传言说它可能会在未来的React版本中被删除。始终在componentDidMount中进行异步副作用请求,并在componentWillUnmount中清理它们。即使您没有要渲染的内容,最好也要渲染一个占位符组件,直到数据到达(快速加载的最佳选项),或者根本不渲染。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接