在click react.js上切换列表的背景颜色

时间:2015-07-14 17:06:36

标签: javascript jquery reactjs

我正在尝试创建一个具有以下功能的列表。

  1. 在悬停时更改listItem的背景颜色。
  2. 单击更改listItem的背景颜色。
  3. 在点击的元素之间切换背景颜色。列表中只有一个元素可以点击属性]
  4. 我已经执行了onhover 1和2功能,但我无法实现第3个功能。请帮我解决这个问题。

    提前致谢。

    /** @jsx React.DOM */
    
       'use strict'
    
        var React = require('react')
    
    
        var ListItem = React.createClass({
    
            getInitialState: function() {
                return  {hover_flag: false, click_flag: false}
            },
    
            hoverEvent: function() {
                this.setState({hover_flag: !this.state.hover_flag})
            },
    
            clickEvent: function(){
                this.setState({click_flag: true})
            },
    
            render: function() {
                var liStyle = {
                    /* some more class properties */
                    background: '#cc181e',
                }
    
                if(this.state.hover_flag || this.state.click_flag) {
                    liStyle['background'] = '#880000'
                }
    
                if(this.state.click_flag) {
                    liStyle['background'] = '#880000'           
                }
    
                return (
                    <li onClick={this.clickEvent} onMouseEnter={this.hoverEvent} onMouseLeave={this.hoverEvent} style={liStyle} key={this.props.name}>{this.props.name}</li>
                )
            }
    
        })
    
    
        module.exports = React.createClass({
    
            render: function() {
    
                var ulStyle = {
                    padding: '0px',
                    margin: '20px',
                }
    
                var link = {
                    textDecoration: 'none',
                    color: 'white',
                    cursor: 'pointer'       
                }
    
    
                var list = this.props.data.map(function(data) {
                    /*List of li elements */
                    return <ListItem name={data.name} />
                })
    
                return (
    
                    <ul style={ulStyle}>
                        {list}
                    </ul>
    
                )
            }
    
        });
    

2 个答案:

答案 0 :(得分:6)

在查看任何代码之前,请考虑问题的实际原因。在当前的实现中,每个ListItem都维护自己的click_flag状态。单击一个ListItem时,它会将自己的click_flag设置为true,但这不会触发其他ListItem将其自己的click_flag重置为false。这是问题的原因。解决方案是将click_flag作为道具从父项传递给每个ListItem。父母有责任确保只有ListItem才能将prop视为true,而其他则为false。同样,ListItem负责通过从父代传下来的回调道具点击它时通知父母。

因此,ListItem看起来像:

var ListItem = React.createClass({
    propTypes: {
        onClick: React.PropTypes.func.isRequired,
        isSelected: React.PropTypes.bool
    },
    getDefaultProps: function() {
        return {
            isSelected: false
        };
    },
    getInitialState: function() {
        return {
            hover_flag: false
        };
    },
    hoverEvent: function() {
        this.setState({hover_flag: !this.state.hover_flag});
    },
    render: function() {
        var liStyle = {
            background: '#cc181e'
        };
        if (this.props.isSelected || this.state.hover_flag) {
            liStyle['background'] = '#880000';
        }
        return (
            <li
                onClick={this.props.onClick}
                onMouseEnter={this.hoverEvent}
                onMouseLeave={this.hoverEvent}
                style={liStyle}>{this.props.name}
            </li>
        );
    }
});

并且,父母可能看起来像这样:

module.exports = React.createClass({
    getInitialState: function() {
        return {
            selectedItem: null
        };
    },
    clickHandler: function(idx) {
        this.setState({selectedItem: idx});
    },
    render: function() {
        var ulStyle = {
            padding: '0px',
            margin: '20px'
        };
        var items = this.props.data.map(function (item, idx) {
            var is_selected = this.state.selectedItem == idx;
            return <ListItem
                key={item.name}
                name={item.name}
                onClick={this.clickHandler.bind(this, idx)}
                isSelected={is_selected}
                />;
        }.bind(this));
        return (
            <ul style={ulStyle}>
                {items}
            </ul>
        );
    }
});

父级维护状态变量,该变量存储哪个ListItem是当前选定的ListItem。它在render()中使用此状态将is_selected = true传递给一个ListItem,并将所有其他传递给false。父对象的状态由clickHandler更新,clickHandler作为props传递给每个ListItem。见example fiddle here

答案 1 :(得分:1)

由于只有一个选定的项目,父组件可以维持具有所选项目索引的状态。

父组件

getInitialState: function(){
  return {selectedItem : null, items: this.props.data};
}

将render方法更改为类似的方法(注意发送给ListItem组件的isSelected属性)

var selectedItem = this.state.selectedItem;
var list = this.state.items.map(function(data) {
  /*List of li elements */
  return <ListItem name={data.name} onSelect={this.onSelectHandler} isSelected={selectedItem === data.id} key={data.id}/> // <--- I would suggest having a unique ID
});

让我们稍后实现onSelectHandler。

<强>列表项

在定义转移中,prop被选择为ListItem的状态

getInitialState: function(){
  return  {hover_flag: false, click_flag: this.props.isSelected} // <---- notice the change here
}

现在修改clickEvent并触发ListItem的onSelect属性并发送单击的ListItem的名称(我也建议在这里使用一个唯一的ID)

clickEvent: function(){
  this.setState({click_flag: true});
  this.props.onSelect(this.props.name); // <--- I would suggest sending ID
}

让我们为父组件实现onSelectHandler

onSelectHandler: function(childItemID){
  this.setState({selectedItem: childItemID});
}

希望这是有道理的