Javascript 反应-更改单个跨度类的背景不起作用
我是一个新的反应者,所以如果我的问题或我试图实现的事情很奇怪,我表示歉意(请告诉我是否有更好/更符合逻辑的方法来实现这一点) 我在我的React应用程序中使用了Javascript 反应-更改单个跨度类的背景不起作用,javascript,reactjs,react-native,fabricjs,Javascript,Reactjs,React Native,Fabricjs,我是一个新的反应者,所以如果我的问题或我试图实现的事情很奇怪,我表示歉意(请告诉我是否有更好/更符合逻辑的方法来实现这一点) 我在我的React应用程序中使用了列表结构React组件,该组件基于列表GridExample组件,该组件位于以下位置: 我已经设置好了,但似乎无法完成以下任务: 单击列表组件中的span类(实际上是一个项目)时,我想更改其背景色,为此,我按照以下帖子中的说明进行操作: 这是一个相当简单的示例,但这会将我所有的网格单元/span类更改为蓝色,而不仅仅是单击的颜色。有没
列表
结构React
组件,该组件基于列表GridExample
组件,该组件位于以下位置:
我已经设置好了,但似乎无法完成以下任务:
单击列表
组件中的span类
(实际上是一个项目)时,我想更改其背景色
,为此,我按照以下帖子中的说明进行操作:
这是一个相当简单的示例,但这会将我所有的网格单元/span类
更改为蓝色,而不仅仅是单击的颜色。有没有办法让点击的span类改变它的背景
初始状态:
单击一个跨度类后的状态(错误):
实现代码(包括一些不必要的代码):
class UrenBoekenGrid extends React.Component {
constructor(props) {
super(props);
this.state = {
bgColor: 'red'
}
}
render() {
return (
<FocusZone>
<List
items={[
{
key: '#test1',
name: 'test1',
},
{
name: 'test2',
key: '#test2',
},
{
name: 'test3',
key: '#test3',
},
{
name: 'test4',
key: '#test4',
},
..... up to 32 items
]}
onRenderCell={this._onRenderCell}
/>
</FocusZone>
);
}
changeColor(item){
this.setState({bgColor: 'blue'});
console.log('clicked item == ' + item.name)
}
_onRenderCell = (item, index) => {
return (
<div
className="ms-ListGridExample-tile"
data-is-focusable={true}
style={{
width: 100 / this._columnCount + '%',
height: this._rowHeight * 1.5,
float: 'left'
}}
>
<div className="ms-ListGridExample-sizer">
<div className="msListGridExample-padder">
{/* The span class with the click event: */}
<span className="ms-ListGridExample-label" onClick={this.changeColor.bind(this, item)} style={{backgroundColor:this.state.bgColor}}>{`item ${index}`}</span>
<span className="urenboeken-bottom"></span>
</div>
</div>
</div>
);
};
}
现在,在我的列表
呈现中,我已将项目设置为状态项目
数组,并在\u onRenderCell
函数中添加了onClick
事件:
render() {
return (
<FocusZone>
<List
items={this.state.items}
getItemCountForPage={this._getItemCountForPage}
getPageHeight={this._getPageHeight}
renderedWindowsAhead={4}
onRenderCell={this._onRenderCell}
/>
</FocusZone>
);
}
_onRenderCell = (item, index) => {
return (
<div
className="ms-ListGridExample-tile"
data-is-focusable={true}
style={{
width: 100 / this._columnCount + '%',
height: this._rowHeight * 1.5,
float: 'left'
}}
>
<div className="ms-ListGridExample-sizer">
<div className="msListGridExample-padder">
<span className="ms-ListGridExample-label"
onClick={this.onClick(item.name)}
style={{backgroundColor: item.bgColor}}
>
{`item ${index}`}
</span>
<span className="urenboeken-bottom"></span>
</div>
</div>
</div>
);
};
但这也将删除列表
组件功能及其响应功能
因此,我的最后一个想法是用整个onClick
div替换列表中的项
,并删除\u onRenderCell
函数本身,但这会使页面空白(再也看不到单元格了):
render(){
返回(
(
this.onClick(item.name)}style={{{backgroundColor:item.bgColor}>
{item.name}
))}
getItemCountForPage={this.\u getItemCountForPage}
getPageHeight={this.\u getPageHeight}
renderedWindowsAhead={4}
//onRenderCell={this.\u onRenderCell}
/>
);
}
我认为cssms类
/div也应该在那里,因为它们具有高度/宽度属性,但是添加它们(与\u onRenderCell
函数完全一样)没有任何区别,页面仍然是空白的。实际上您正在更改所有span元素的颜色,当您为每个跨度设置样式时,请将其设置为状态变量bgColor
相反,您应该保存单击的项目,并根据以下内容决定颜色:
this.state = {
bgColor: 'red',
clickedColor: 'blue
}
在构造函数中
然后在单击处理程序中:
changeColor(item){
this.setState({selected: item.name});
console.log('clicked item == ' + item.name)
}
因此在渲染器中(我只放置了相关部分):
{`item${index}}
问题在于,您正在网格状态中存储背景颜色,并将此状态分配给网格的每个元素,因此如果您更新状态,它将影响每个元素。最好是为网格元素创建一个单独的组件,并在其中存储它们自己的状态,或者如果只想使用一个状态,则将项
数组存储在状态中,并为它们添加一个新的bgColor
属性,因此如果只想更改一个项的背景色,您需要为items
数组的特定对象调用setstate
下面是一个小例子(我没有测试它):
类UrenBoekenGrid扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
项目:[
{
键:“#test1”,
名称:“test1”,
bgColor:'蓝色',
},
],
};
}
onClick(名称){
this.setState(prevState=>({
items:prevState.items.map(item=>{
如果(item.name==名称){
item.bgColor='红色';
}
退货项目;
})
}))
}
render(){
{this.state.items.map(item=>(
this.onClick(item.name)}style={{{backgroundColor:item.bgColor}>
{item.name}
))}
}
}
非常感谢您的回答,这似乎是一条可行之路,但我似乎无法在现有的列表组件中实现您的解决方案。我已经用遇到的问题更新了我的主要帖子(在更新部分)。不客气:)似乎您正在更新一个render()
或constructor()
函数中的状态,它会导致无限循环。能否显示构造函数和/或呈现方法?这可能导致问题:onClick={this.onClick(item.name)}
。在这里,当呈现组件时,您将调用onClick方法。尝试将其更改为onClick={()=>this.onClick(item.name)}
您完全正确。再次感谢您,将onClick={this.onClick(item.name)}
替换为onClick={()=>this.onClick(item.name)}
就可以了!愚蠢的我错过了!
render() {
return (
<FocusZone>
<List
items={this.state.items.map(item => (
<div onClick={() => this.onClick(item.name)} style={{backgroundColor: item.bgColor}}>
{item.name}
</div>
))}
getItemCountForPage={this._getItemCountForPage}
getPageHeight={this._getPageHeight}
renderedWindowsAhead={4}
// onRenderCell={this._onRenderCell}
/>
</FocusZone>
);
}
this.state = {
bgColor: 'red',
clickedColor: 'blue
}
changeColor(item){
this.setState({selected: item.name});
console.log('clicked item == ' + item.name)
}
<span ... style={{backgroundColor: (item.name === this.state.selected ? this.state.clickedColor : this.state.bgColor)}}>{`item ${index}`}</span>
class UrenBoekenGrid extends React.Component {
constructor(props) {
super(props);
this.state = {
items: [
{
key: '#test1',
name: 'test1',
bgColor: 'blue',
},
],
};
}
onClick(name) {
this.setState(prevState => ({
items: prevState.items.map(item => {
if (item.name === name) {
item.bgColor = 'red';
}
return item;
})
}))
}
render() {
<div>
{this.state.items.map(item => (
<div onClick={() => this.onClick(item.name)} style={{backgroundColor: item.bgColor}}>
{item.name}
</div>
))}
</div>
}
}