繁体   English   中英

在OnMouseOver事件中设置状态会返回TypeError:无法读取属性-React

[英]Setting state in OnMouseOver event returns TypeError: Cannot read property - React

尽管找到了有关此错误的大量帖子,但我似乎无法针对我的具体情况进行修复。

我有一组项目,当您将鼠标悬停在它们上时,我正在尝试为这些项目(div)着色。 着色发生在当state这些资料( reserved )为假,并且该starting state被设置为真。 因此,当单击一个项目( MouseDown事件)时,我正在设置starting condition (状态为true),然后当我将鼠标悬停在下一个项目上并且起始条件为true且被鼠标悬停的项目时,其reserved state property设置为如果为false,则应更改其背景颜色,以此类推。

现在,可以按照以下步骤进行操作:

在(初始)状态下定义项目和开始条件:

constructor(props) {
    super(props);

    this.state = {
        items: [
            {
                name: 'test1',
                key: '#test1',
                reserved: false,
            },
            {
                name: 'test2',
                key: '#test2',     
                reserved: false, 
            },
            {
                name: 'test3',
                key: '#test3',
                reserved: false,  
            },
            {
                name: 'test4',
                key: '#test4',
                reserved: false,  
            },
            {
                name: 'test5',
                key: '#test5',
                reserved: false,   
            },
        ],

        startCondition: false

    }
}

渲染列表项:

render() {

  return (    
    <FocusZone>
      <List
        items={this.state.items}
        onRenderCell={this._onRenderCell}
      />
    </FocusZone>
  );
}

_onRenderCell事件中,我正在渲染每个单元格(项目div)并设置onMouseDownonMouseUponMouseOver事件,我还在此处检查该项目的reserved状态,以便当该项目变为reserved = true它将获得一个额外的css classcss class包含不同的背景色:

_onRenderCell = (item, index) => {

    let className = 'ms-ListGridExample-label';

    if (item.reserved === true) {
        className += ' reservation-creating';
    }

    return (
      <div
        className="ms-ListGridExample-tile"
        data-is-focusable={false}
        style={{
          width: 100 / this._columnCount + '%',
          height: this._rowHeight * 1.5,
          float: 'left'
        }}
      >
        <div className="ms-ListGridExample-sizer">
          <div className="msListGridExample-padder">

            <span className={className}
                 onMouseOver={() => this._onMouseOver(item.name)} 
                 onMouseUp={() => this._onMouseUp(item)} 
                 onMouseDown={() => this._onMouseDown(item.name)} 
            >
                {item.name}

            </span>

            <span className="urenboeken-bottom"></span>
          </div>
        </div>
      </div>
    );
};

因此,当单击一个项目( MouseDown事件)时,它将开始条件设置为true,还将其设置为reserved ,以为其提供额外的css classbackground color不同):

_onMouseDown(name){
    if (this.state.startCondition === false){
        this.setState({startCondition: true});

        this.setState(prevState => ({
            items: prevState.items.map(item => {

                if (item.name === name) {
                    if (item.reserved === true)
                    {
                        item.reserved = false
                    }
                    else if (item.reserved === false)
                    {
                        item.reserved = true
                    }
                    else
                    {
                        item.reserved = false
                    }
                }
                return item;
            })
        }))
    }
}

触发MouseDown事件并设置Start Condition ,将使用MouseOver事件跟踪移动,并将reserved state设置为true:

 _onMouseOver(name) {
    if (this.state.startCondition === true) {

        this.setState(prevState => ({
            items: prevState.items.map(item => {
                if (item.reserved === false) {
                    if (item.name === name) {
                        item.reserved = true
                    }

                    return item;
                }
            })
        })) 
    }
}

此时,再次触发_OnRenderCell并返回错误:

MyClass.js:265 Uncaught TypeError: Cannot read property 'reserved' of undefined
    at MyClass._this._onRenderCell

_onRenderCell函数的以下部分:

if (item.reserved === true) 

我可能正在做一些明显的错误,但是我似乎无法指出这是什么。

Ps onMouseUp事件将starting condition重置为false。

UPDATE

应@ M.Fazio的要求,他怀疑List渲染中的items={this.state.items}部分出了问题,我添加了一条日志,以显示渲染前项目中的内容:

render() {
    let tItems; 

    tItems = this.state.items.map(item => { 
        console.log('Item name = ' + item.name + ' item reserved = ' + item.reserved);
    });  

  return (  

    <FocusZone>
      <List
        items={this.state.items}
        onRenderCell={this._onRenderCell}
      />
    </FocusZone>
  );
}

结果:

在此处输入图片说明

需要指出的一些事情:

  • 对于数组中的每个项目(逻辑上),都会调用OnRenderCell
  • List渲染似乎发生了三次,为什么?
  • 在执行此过程时( onMouseDown + onMouseOver事件),将发生以下情况(添加的日志中实际上已经发生了错误): 在此处输入图片说明

@ M.Fazio找到了解决方案。 最后,这是一个小故障(尽管很难为自己找到)。 return item; _onMouseOver事件中的if condition位于if condition内部,将其移至if condition之外使其有效!

ListComponent ,当调用onRenderCell ListComponent时,必须传递参数。 你是否 ? 也许过去了ListComponent的代码,所以我们可以为您ListComponent帮助?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM