[英]Toggle background color of list on click react.js
我正在嘗試創建一個具有以下功能的列表。
我已經執行了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>
)
}
});
在查看任何代碼之前,請考慮問題的實際原因。 在當前的實現中,每個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。 請參見示例小提琴
由於只有一個選定項,因此父組件可以維持具有所選項索引的狀態。
父組件
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});
}
希望這是有道理的
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.