反应-更改单个span类的背景不起作用

时间:2018-08-07 09:35:20

标签: javascript reactjs react-native fabricjs

我是React的新手,所以如果这个问题或我要解决的问题很奇怪(请告诉我是否有更好/更多的逻辑方法可以这样做),我深表歉意。

我在我的React应用程序中使用List Fabric React组件,该组件基于ListGridExample组件,可在以下位置找到: https://developer.microsoft.com/en-us/fabric#/components/list

我已经设置好了,但似乎无法完成以下操作:

当单击span class组件中的List(实际上是项目)时,我想将其更改为background color,为此,我按照以下说明进行操作帖子: https://forum.freecodecamp.org/t/react-js-i-need-a-button-color-to-change-onclick-but-cannot-determine-how-to-properly-set-and-change-state-for-that-component/45168

这是一个非常简单的示例,但是将我所有的grid cells / span classes更改为蓝色,而不仅仅是单击的颜色。有没有一种方法可以使单击的span类更改其背景?

初始状态: enter image description here

单击一个跨度类后的状态(这是错误的): enter image description here

实施代码(省略了一些不必要的代码):

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


}

我现在将click event附加到span class本身,但我认为将click event放在item(s)(数组)本身上是更合理的选择,但是我也找不到实现这一目标的方法。

---- UPDATE ----

@peetya答案似乎可行,因为@Mario Santini答案仅更新单个单元格,如果单击了另一个单元格,则前一个单元格将恢复正常并失去其颜色。

所以我要做的是将items array添加到state并为其添加bgColor属性:

this.state = {
        items: [
            {
                key: '#test1',
                name: 'test1',
                bgColor: 'blue',
            },
            {
                name: 'test2',
                key: '#test2',   
                bgColor: 'blue',    
            },
            {
                name: 'test3',
                key: '#test3',
                bgColor: 'blue',    
            },
            {
                name: 'test4',
                key: '#test4',
                bgColor: 'blue',    
            },
        ],
     }

现在,在我的List渲染中,我已将项目设置为state items数组,并在onClick函数中添加了_onRenderCell事件:

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 event函数中添加_onRenderCell,因为这会产生以下错误:

enter image description here

我想保留Fabric List component,因为它还具有渲染/调整屏幕大小,完全删除列表组件并仅用@peetya建议的功能替换它的功能:

render() {
        <div>
            {this.state.items.map(item => (
                <div onClick={() => this.onClick(item.name)} style={{backgroundColor: item.bgColor}}>
                    {item.name}
                </div>
            ))}
        </div>
    }

但这也将通过其List函数删除responsive组件功能。

所以我的最后一个想法是将items的{​​{1}}替换为整个List div并删除onClick函数本身,但这使页面空白(再也看不到单元格了。):

_onRenderCell

我认为也许css 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> ); } / div也应该在其中,因为它们具有height / width属性,但是添加它们(与ms-classes函数完全一样)并没有什么区别,页面仍为空白。

2 个答案:

答案 0 :(得分:1)

实际上,您正在更改所有span元素的颜色,因为您为每个span样式设置了状态变量 bgColor

Insteas,您应该保存单击的项目,然后根据其确定颜色:

BB

在构造函数中。

然后在点击处理程序中:

 /usr/pgsql-9.6/bin/pg_ctl restart -D /var/lib/pgsql/9.6/db1
 /usr/pgsql-9.6/bin/pg_ctl restart -D /var/lib/pgsql/9.6/db2
 /usr/pgsql-9.6/bin/pg_ctl restart -D /var/lib/pgsql/9.6/db3

因此,在渲染器中(我只放入了相关部分):

this.state = {
    bgColor: 'red',
    clickedColor: 'blue
}

答案 1 :(得分:1)

问题在于您将背景色存储在网格状态中,并将此状态分配给网格中的每个元素,因此,如果更新状态,它将影响每个元素。最好的方法是,为Grid元素创建一个单独的组件并在其中存储它们自己的状态,或者如果您只想使用一个状态,然后在状态内存储items数组并添加一个新的{{1} }属性,因此,如果您只想更改一项的背景色,则需要为bgColor数组的特定对象调用setEstate。

这是一个小例子(我没有测试过):

items