【问题标题】:How to add a class with React.js?如何使用 React.js 添加一个类?
【发布时间】:2015-10-21 14:48:06
【问题描述】:

单击按钮后我需要添加“活动”类并删除所有其他“活动”类。

请看这里:https://codepen.io/azat-io/pen/RWjyZX

var Tags = React.createClass({
  setFilter: function(filter) {
    this.props.onChangeFilter(filter);
  },
  render: function() {
    return <div className="tags">
      <button className="btn active" onClick={this.setFilter.bind(this, '')}>All</button>
      <button className="btn" onClick={this.setFilter.bind(this, 'male')}>male</button>
      <button className="btn" onClick={this.setFilter.bind(this, 'female')}>female</button>
      <button className="btn" onClick={this.setFilter.bind(this, 'child')}>child</button>
      <button className="btn" onClick={this.setFilter.bind(this, 'blonde')}>blonde</button>
     </div>
  }
});

var Kid = React.createClass({
  render: function() {
    return <ul>
      <li>{this.props.name}</li>
      </ul>
  }
});

var List = React.createClass({
  getInitialState: function() {
    return {
      filter: ''
    };
  },
  changeFilter: function(filter) {
    this.setState({
      filter: filter
    });
  },
  render: function() {
    var list = this.props.Data;

    if (this.state.filter !== '') {
      list = list.filter((i)=> i.tags.indexOf(this.state.filter) !== -1);
      console.log(list);
    } 

    list = list.map(function(Props){
      return <Kid {...Props} />
    });

    return <div>
      <h2>Kids Finder</h2>
      <Tags onChangeFilter={this.changeFilter}/>
      {list}
    </div>
  }
});

var options = {
  Data:  [{
    name: 'Eric Cartman',
    tags: ['male', 'child']
  },{
    name: 'Wendy Testaburger',
    tags: ['female', 'child']
  },{
    name: 'Randy Marsh',
    tags: ['male']
  },{
    name: 'Butters Stotch',
    tags: ['male', 'blonde', 'child']
  },{
    name: 'Bebe Stevens',
    tags: ['female', 'blonde', 'child']
  }]
};

var element = React.createElement(List, options);
React.render(element, document.body);

我怎样才能在这里做得更好?

【问题讨论】:

  • 我建议制作一个“按钮”组件,而不是仅仅在“标签”组件下呈现一堆链接。然后对于每个按钮,您可以有条件地有条件地设置 className 属性。这可能会有所帮助:github.com/JedWatson/classnames
  • @JohnGibbons,我不想添加任何其他实用程序。我认为这很简单。使用 . 更新 codepen 项目
  • 记住在组件状态下点击了哪个按钮。

标签: javascript jquery reactjs


【解决方案1】:

这很简单。 看看这个

https://codepen.io/anon/pen/mepogj?editors=001

基本上您想处理组件的状态,以便检查当前活动的状态。你需要包括

getInitialState: function(){}
//and 
isActive: function(){}

查看链接上的代码

【讨论】:

  • 我见过的最好的解决方案。恭喜!
  • 这方面有更详细的说明吗?我很难理解这个例子。
  • 嗨,我正在尝试做同样的事情,但使用的是 redux。问题是当 this.props 改变时我的 isActive() 方法没有被触发。有什么帮助吗?泰
  • isActive 方法将在每次组件呈现时触发。并且每次属性更改时都会发生这种情况,在您的情况下,由于您使用的是 redux,因此可能发生的是您的树不是不可变的,因此不会重新渲染组件,因为它没有检测到状态更改。
【解决方案2】:

这非常有用:

https://github.com/JedWatson/classnames

你可以做类似的事情

classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'

// lots of arguments of various types
classNames('foo', { bar: true, duck: false }, 'baz', { quux: true }); // => 'foo bar baz quux'

// other falsy values are just ignored
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1'

或者像这样使用它

var btnClass = classNames('btn', this.props.className, {
  'btn-pressed': this.state.isPressed,
  'btn-over': !this.state.isPressed && this.state.isHovered
});

【讨论】:

【解决方案3】:

取自他们的网站。

render() {
  let className = 'menu';
  if (this.props.isActive) {
    className += ' menu-active';
  }
  return <span className={className}>Menu</span>
}

https://reactjs.org/docs/faq-styling.html

【讨论】:

    【解决方案4】:

    由于您已经有&lt;Tags&gt; 组件在其父组件上调用函数,因此您不需要额外的状态:只需将过滤器作为道具传递给&lt;Tags&gt; 组件,并使用它来呈现您的按钮。像这样:

    &lt;Tags&gt; 组件中的渲染函数更改为:

    render: function() {
      return <div className = "tags">
        <button className = {this._checkActiveBtn('')} onClick = {this.setFilter.bind(this, '')}>All</button>
        <button className = {this._checkActiveBtn('male')} onClick = {this.setFilter.bind(this, 'male')}>male</button>
        <button className = {this._checkActiveBtn('female')} onClick = {this.setFilter.bind(this, 'female')}>female</button>
        <button className = {this._checkActiveBtn('blonde')} onClick = {this.setFilter.bind(this, 'blonde')}>blonde</button>
      </div>
    },
    

    并在&lt;Tags&gt;中添加一个函数:

    _checkActiveBtn: function(filterName) {
      return (filterName == this.props.activeFilter) ? "btn active" : "btn";
    }
    

    在您的&lt;List&gt; 组件中,将过滤器状态作为道具传递给&lt;tags&gt; 组件:

    return <div>
      <h2>Kids Finder</h2> 
      <Tags filter = {this.state.filter} onChangeFilter = {this.changeFilter} />
      {list}
    </div>
    

    然后它应该按预期工作。 Codepen here(希望链接有效)

    【讨论】:

      【解决方案5】:

      您也可以使用纯 js 来完成此操作,就像使用 jquery 的旧方法一样

      如果你想要一个简单的方法试试这个

       document.getElementById("myID").classList.add("show-example");
      

      【讨论】:

      • 虽然这在技术上可能可行,但阅读这样的代码会非常棘手。
      • 不是真的,我只是试图提供一个可行的替代解决方案。无论如何感谢您的评论。
      • 除非在钩子中正确使用它,否则这可能与可能在应用程序中引入错误的虚拟 DOM 不匹配。
      【解决方案6】:
      const activeState = (e)=>{
          var id = e.target.id
          const idArray = ["homeBtn","aboutBtn","servicesBtn","portfolioBtn","testmBtn","blogBtn","contactBtn"]
      
          idArray.forEach((element)=> {
              document.getElementById(element).classList.remove("active")
          });
          console.log(id);
          document.getElementById(id).classList.add("active")
      
      }
      

      【讨论】:

      • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
      猜你喜欢
      • 2020-02-17
      • 2014-12-28
      • 1970-01-01
      • 1970-01-01
      • 2021-11-12
      • 1970-01-01
      • 2020-06-13
      • 2016-09-21
      • 2020-07-02
      相关资源
      最近更新 更多