Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to set hover in a React loop and effect only one instead of all elements in the loop?

When I use setHover it reflects to all list data which returned from map loop. How can I use hover to reflect on itself element?

  const [hover, setHover] = useState(true)

  function MouseOver(event) {
    setHover(true)
  }
  function MouseOut(event){
    setHover(false)
  }

  {data.map((item, index) => (

    //When I hover parent div I want to show the {item.arrow} div inside and not all {item.arrow} divs in the loop

    <div key={index} onMouseEnter={MouseOver} onMouseLeave={MouseOut} className="flex gap-3">
      <div>
        {item.content}
      </div>
      
      <div hidden={hover}>
        {item.arrow}
      </div>
    </div>
  ))}

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

If the state does not need to be controlled by the parent you can create a new component to use in the list.

Each component will then control its own hover state.

const List = ({data}) => {
    return (
        <div>
        {
            data.map((item, index) => (<Item key={index} item={item} />))
        }
        </div>
    )
}

const Item = ({item}) => {
    const [hover, setHover] = useState(true)

    const mouseOver = (event) => {
        setHover(true)
    }

    const mouseOut = (event) => {
        setHover(false)
    }

    return (
        <div onMouseEnter={mouseOver} onMouseLeave={mouseOut} className="flex gap-3">
            <div>
                {item.content}
            </div>
            <div hidden={hover}>
                {item.arrow}
            </div>
        </div>
    );
}

If the state does need to be controlled by the parent you can use a Record<number, boolean> to store the states.

const List = ({data}) => {
    const [hover, setHover] = useState({})

    const mouseOver = (event, index) => {
        setHover(c => {
            return {
                ...c,
                [index]: true
            };
        })
    }

    const mouseOut = (event, index) => {
        setHover(c => {
            return {
                ...c,
                [index]: false
            };
        })
    }

    return (
        <div>
        {
            data.map((item, index) => (
                <div 
                    key={index} 
                    onMouseEnter={(e) => {
                        mouseOver(e, index);
                    }} 
                    onMouseLeave={(e) => {
                        mouseOut(e, index);
                    }} 
                    className="flex gap-3"
                >
                    <div>
                        {item.content}
                    </div>
                    <div hidden={hover[index]}>
                        {item.arrow}
                    </div>
                </div>
            ))
        }
        </div>
    )
}

If the state is not needed for anything other than hiding a div you could also just use CSS.

CSS will not require the component to rerender everytime you hover over it.

CSS

.hoverable-show {
    display: none;
}

.hoverable-item:hover .hoverable-show {
    display: block;
}

JS

const List = ({data}) => {
    return (
        <div>
        {
            data.map((item, index) => (
                <div
                    className="flex gap-3 hoverable-item"
                >
                    <div>
                        {item.content}
                    </div>
                    <div className="hoverable-show">
                        {item.arrow}
                    </div>
                </div>
            ))
        }
        </div>
    )
}

Preference should be CSS -> Individual State -> Parent (list) State.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading