Javascript 在状态改变时反应改变类名

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35224113/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 17:25:39  来源:igfitidea点击:

react change class name on state change

javascriptreactjs

提问by gamer

I have a state like this where I am setting activeand classflag like this:

我有一个这样的状态,我正在设置activeclass标记这样的:

constructor(props) {
  super(props);
  this.state = {'active': false, 'class': 'album'};
}

handleClick(id) {
  if(this.state.active){
    this.setState({'active': false,'class': 'album'})
  }else{
    this.setState({'active': true,'class': 'active'})
  }
}

And I have a list of items with class name from state:

我有一个带有状态类名称的项目列表:

<div className={this.state.class} key={data.id} onClick={this.handleClick.bind(this.data.id}>
  <p>{data.name}</p>
</div>

Here how can I change the class name of particular div?

这里如何更改特定 div 的类名?

回答by Jon Surrell

Below is a fully functional example of what I believe you're trying to do (with a functional snippet).

下面是我认为您正在尝试做的功能齐全的示例(带有功能片段)。

Explanation

解释

Based on your question, you seem to be modifying 1 property in statefor all of your elements. That's why when you click on one, all of them are being changed.

根据您的问题,您似乎正在state为所有元素修改 1 个属性。这就是为什么当您单击一个时,所有这些都将被更改。

In particular, notice that the state tracks an index of whichelement is active. When MyClickableis clicked, it tells the Containerits index, Containerupdates the state, and subsequently the isActiveproperty of the appropriate MyClickables.

特别要注意,状态跟踪哪个元素处于活动状态的索引。当MyClickable被点击时,它告诉Container它的索引,Container更新state,随后isActive相应的财产MyClickable秒。

Example

例子

class Container extends React.Component {
  state = {
    activeIndex: null
  }

  handleClick = (index) => this.setState({ activeIndex: index })

  render() {
    return <div>
      <MyClickable name="a" index={0} isActive={ this.state.activeIndex===0 } onClick={ this.handleClick } />
      <MyClickable name="b" index={1} isActive={ this.state.activeIndex===1 } onClick={ this.handleClick }/>
      <MyClickable name="c" index={2} isActive={ this.state.activeIndex===2 } onClick={ this.handleClick }/>
    </div>
  }
}

class MyClickable extends React.Component {
  handleClick = () => this.props.onClick(this.props.index)
  
  render() {
    return <button
      type='button'
      className={
        this.props.isActive ? 'active' : 'album'
      }
      onClick={ this.handleClick }
    >
      <span>{ this.props.name }</span>
    </button>
  }
}

ReactDOM.render(<Container />, document.getElementById('app'))
button {
  display: block;
  margin-bottom: 1em;
}

.album>span:after {
  content: ' (an album)';
}

.active {
  font-weight: bold;
}

.active>span:after {
  content: ' ACTIVE';
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js"></script>
<div id="app"></div>

Update: "Loops"

更新:“循环”

In response to a comment about a "loop" version, I believe the question is about rendering an array of MyClickableelements. We won't use a loop, but map, which is typical in React + JSX. The following should give you the same result as above, but it works with an array of elements.

在回应关于“循环”版本的评论时,我相信问题是关于渲染MyClickable元素数组。我们不会使用循环,而是使用map,这在 React + JSX 中很典型。以下应该为您提供与上述相同的结果,但它适用于元素数组。

// New render method for `Container`
render() {
  const clickables = [
    { name: "a" },
    { name: "b" },
    { name: "c" },
  ]

  return <div>
      { clickables.map(function(clickable, i) {
          return <MyClickable key={ clickable.name }
            name={ clickable.name }
            index={ i }
            isActive={ this.state.activeIndex === i }
            onClick={ this.handleClick }
          />
        } )
      }
  </div>
}