React useRef() not working onMouseOver to change backgroundColor of div

I am new to React. My issue is that I am trying to change the background color of a div that I dynamically render in React. To do this I learned about useRef() to single out the element.

If I do a console.log() in the onHover function, the log works in the browser, but the background color of the element does not change for some reason, even though I have implemented useRef how others have for this exact same reason.

Thank you in advance for your help, here is the code:

import React, { useRef } from "react";

const CountiesList = () => {
    const counties = [
        'Antrim',
        'Armagh',
        'Carlow',
        'Cavan',
        'Clare',
        'Cork',
        'Derry',
        'Donegal',
        'Down',
        'Dublin',
        'Fermanagh',
        'Galway',
        'Kerry',
        'Kildare',
        'Kilkenny',
        'Laois',
        'Leitrim',
        'Limerick',
        'Longford',
        'Louth',
        'Mayo',
        'Meath',
        'Monaghan',
        'Offaly',
        'Roscommon',
        'Sligo',
        'Tipperary',
        'Tyrone',
        'Waterford',
        'Westmeath',
        'Wexford',
        'Wicklow'
    ]

    const liItem = useRef(null)
    
    const onHover = () => {
        liItem.current.style.backgroundColor = 'cornflowerblue'
    }
        
    const ulStyle = {
        listStyleType: 'none',
        paddingInlineStart: 0,
        margin: 0,
        width: '100%',
        height: '300px',
        overflowY: 'scroll',
        borderBottomLeftRadius: '12px'
    }
        
    const liItemContainer = {
        height: '50px',
        paddingLeft: '15px',
        display: 'flex',
        alignItems: 'center',
        backgroundColor: '#a9c4f5'
    }
        
    const liStyle = {
        fontWeight: '700'
    }
        
    let countiesListItems = counties.map(county => {
        return (
            <div ref={liItem} key={county} style={liItemContainer} onMouseOver={onHover}>
                <li style={liStyle}>{county}</li>
            </div>
        )
    })
        
    return (
        <ul style={ulStyle}>
            {countiesListItems}
        </ul>
    )
}

export default CountiesList;

>Solution :

That’s because you use a single ref on an array of elements, You need to use an array of template refs or just pass the target element by onMouseOver={(e) => onHover(e.target)} and change the style directly without the need to template refs

import React, { useRef } from "react";

const CountiesList = () => {
    const counties = [
        'Antrim',
        'Armagh',
        'Carlow',
        'Cavan',
        'Clare',
        'Cork',
        'Derry',
        'Donegal',
        'Down',
        'Dublin',
        'Fermanagh',
        'Galway',
        'Kerry',
        'Kildare',
        'Kilkenny',
        'Laois',
        'Leitrim',
        'Limerick',
        'Longford',
        'Louth',
        'Mayo',
        'Meath',
        'Monaghan',
        'Offaly',
        'Roscommon',
        'Sligo',
        'Tipperary',
        'Tyrone',
        'Waterford',
        'Westmeath',
        'Wexford',
        'Wicklow'
    ]

    const liItem = useRef(null)
    
    const onHover = (element) => {
        element.style.backgroundColor = 'cornflowerblue'
    }
        
    const ulStyle = {
        listStyleType: 'none',
        paddingInlineStart: 0,
        margin: 0,
        width: '100%',
        height: '300px',
        overflowY: 'scroll',
        borderBottomLeftRadius: '12px'
    }
        
    const liItemContainer = {
        height: '50px',
        paddingLeft: '15px',
        display: 'flex',
        alignItems: 'center',
        backgroundColor: '#a9c4f5'
    }
        
    const liStyle = {
        fontWeight: '700'
    }
        
    let countiesListItems = counties.map(county => {
        return (
            <div ref={liItem} key={county} style={liItemContainer} onMouseOver={(e) => onHover(e.target)}>
                <li style={liStyle}>{county}</li>
            </div>
        )
    })
        
    return (
        <ul style={ulStyle}>
            {countiesListItems}
        </ul>
    )
}

export default CountiesList;

Leave a Reply