Reputation: 2386
Although finding loads of posts about this error, I can't seem to fix it in my specific case.
I have a set of items and I am trying to color these items (the div's) when you hover over them. The coloring happens when the state
of these items (reserved
) is false and the starting state
is set to true.
So when an item is clicked (MouseDown
event) I am setting the starting condition
(state to true), then when I mouse over the next item, and the start condition is true and the item being moused over has it's reserved state property
set to false, it should change it's background color and so on for the next items which are being moused over.
This is now being done as follows:
Defining the Items and start condition in the (initial) state:
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 the List item:
render() {
return (
<FocusZone>
<List
items={this.state.items}
onRenderCell={this._onRenderCell}
/>
</FocusZone>
);
}
In the _onRenderCell
event I am rendering each cell (item div) and setting the onMouseDown
, onMouseUp
and onMouseOver
events, I also check the reserved
state of the item here so that when the item becomes reserved = true
it gets an extra css class
which contains the different background color:
_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>
);
};
So when an item is clicked (MouseDown
event) it sets the starting condition to true and also set it to reserved
to give it the extra css class
(with it's different background 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;
})
}))
}
}
After the MouseDown
event has been fired and the Start Condition
is being set, the moving will be tracked with the MouseOver
event and setting the reserved state
to 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;
}
})
}))
}
}
At this point, the _OnRenderCell
is fired again and returns me the error:
MyClass.js:265 Uncaught TypeError: Cannot read property 'reserved' of undefined
at MyClass._this._onRenderCell
which is the following part in the _onRenderCell
function:
if (item.reserved === true)
I am probably doing something obvious wrong but I cant seem to point out what it is.
P.s. the onMouseUp
event reset the starting condition
to false.
UPDATE
On request of @M.Fazio, who suspects something is going wrong with the items={this.state.items}
part in the List
rendering, I added a log to display what is inside the items just before rendering:
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>
);
}
Result:
Some things to point out:
OnRenderCell
gets called for every item in the array (which is logical).List
rendering seem to happen three times, why?onMouseDown
+ onMouseOver
event) the following happens (error now actually already happens on the added logging):
Solution
@M.Fazio found the solution. In the end it was a small glitch (though so hard to find for myself).
The return item;
in the _onMouseOver
event was inside the if condition
, moving it outside the if condition
made it working!
Upvotes: 0
Views: 1259
Reputation: 61
In your ListComponent
, when you're calling the onRenderCell
prop, you have to pass your parameters. Did you ?
Maybe past the code of your ListComponent
so we can help you ?
Upvotes: 1