dominik dominik - 25 days ago 8
React JSX Question

React, onMouseOver event trigger all items in list instead of one

I have problem with hovering buttons in list of li's. After hovering one li item button shows in every li item. Link to codepen below the piece of code.

const ItemView = (props) => {
return <li
onMouseOver={() => props.onMouseOver()}
onMouseMove={() => props.onMouseOver()}
onMouseLeave={() => props.onMouseLeave()}
>
<div className="item__row">
<h5>{props.name}</h5>
<h6>Age: {props.age}</h6>
<p>{props.strenght}/100</p>


{props.isHover ? props.children[0] : null}


</div>
{props.children[1]}
</li>


}

Codepen: https://codepen.io/dominik3246/pen/QqKzzp

Answer Source

You need to use an array of element which keeps track of which particular element was hovered. So take isHover state variable as an array like

constructor(){
  ...
  this.state ={
  ...
  isHover: [false, false, false, false, false],
  ...
  }
}

Then make your mouseOver function to return a function containing scope of the index of the item like this

mouseOver(i) {
    return () => {
      if (this.state.isHover[i] === true) {
        return this.state;
      }
      let isHover = [...this.state.isHover]
      isHover[i] = true;
      this.setState({ ...this.state, isHover });
    }
  }

And then to pass isHover and mouseOver prop to your ItemView like this

{this.state.data.map((d, i) => {
          return (
            <ItemView
              key={d.id}
              name={d.name}
              strenght={d.strenght}
              age={d.age}
              onMouseOver={this.mouseOver(i)}
              onMouseLeave={this.mouseExit}
              isHover={this.state.isHover[i]}
            >
            ...

Here is the working example of your code : Link of example