2015-10-21 1 views
39

Не могли бы вы помочь мне с этим довольно простым вопросом. Мне нужно добавить класс «active» после нажатия кнопки и удалить все остальные «активные» классы.Как добавить класс с помощью React.js?

Посмотрите здесь, пожалуйста: http://goo.gl/duLPlG

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); 

Как мне сделать это лучше здесь?

+0

Я бы предложил создать компонент «кнопка», а не просто передать кучу ссылок под ваш компонент «Теги». Затем для каждой кнопки вы можете условно установить атрибут className условно. Это может помочь: https://github.com/JedWatson/classnames –

+1

@JohnGibbons, я не хочу добавлять какие-либо другие утилиты. Я думаю, что это просто. Обновите проект codepen с . –

+0

Помните, какая кнопка была нажата в состоянии компонента. –

ответ

31

Это просто. взглянуть на эту

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

в основном вы хотите иметь дело с состояниями компонента, так что вы проверить текущий активный один. вам нужно будет включить

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

чек из кода по ссылке

+0

Прохладный. Большое спасибо! –

+4

не помешает принять ответ;) –

+6

По-видимому это будет – Chris

4

Поскольку у вас уже есть компонент <Tags>, вызывающий функцию у его родителя, вам не нужно дополнительное состояние: просто передайте фильтр в компонент <Tags> в качестве опоры и используйте это при рендеринге ваших кнопок. Как так:

Измените функцию визуализации внутри <Tags> компонента:

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> 
}, 

И добавить функцию внутри <Tags>:

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

И внутри <List> компонента, передавать состояние фильтра в <tags> Компонент в качестве опоры:

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

Затем он должен работать должным образом. Codepen here (надеюсь, что ссылка работает)

11

это очень полезно:

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 
}); 
+0

classNames отлично, +1 – IliasT