Javascript 反应-更改单个跨度类的背景不起作用

Javascript 反应-更改单个跨度类的背景不起作用,javascript,reactjs,react-native,fabricjs,Javascript,Reactjs,React Native,Fabricjs,我是一个新的反应者,所以如果我的问题或我试图实现的事情很奇怪,我表示歉意(请告诉我是否有更好/更符合逻辑的方法来实现这一点) 我在我的React应用程序中使用了列表结构React组件,该组件基于列表GridExample组件,该组件位于以下位置: 我已经设置好了,但似乎无法完成以下任务: 单击列表组件中的span类(实际上是一个项目)时,我想更改其背景色,为此,我按照以下帖子中的说明进行操作: 这是一个相当简单的示例,但这会将我所有的网格单元/span类更改为蓝色,而不仅仅是单击的颜色。有没

我是一个新的反应者,所以如果我的问题或我试图实现的事情很奇怪,我表示歉意(请告诉我是否有更好/更符合逻辑的方法来实现这一点)

我在我的React应用程序中使用了
列表
结构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}
/>
);
}

我认为css
ms类
/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>
    }
}