React not re-rendering after array state update

I have a checkbox list UI that is rendered from an array. After I update the array the checkbox list state does not update.

I moved the code where the list is mapped but it does not change the results. The DOM re-render does not happen, see gif below.

I have been looking arround and I see that this issue is already reported however the solution about moving the list.map code out of the function it did not work for me.

Could you suggest me a solution? What is the source of this problem?

This is the current state

import React,{ useState } from "react"

import
{
    Box,
    DropButton,
    Grid,
    Text,
    Calendar,
    RangeInput,
    CheckBox
} from "grommet"

const CalButton = ( { label,onSelect } ) =>
{
    return (
        <DropButton
            label={ label }
            dropAlign={ { top: 'bottom',left: 'left' } }
            margin="small"
            dropContent={
                <Box pad="medium" background="ligth-3" elevation="small">
                    <Calendar range size="medium" onSelect={ onSelect } />
                </Box>
            } />
    )
}

const RangeButton = ( { label,value,onChange,min,max,step,unit,header } ) =>
{

    return (
        <DropButton
            label={ value === null ? label : value + ' ' + unit }
            dropAlign={ { top: 'bottom',left: 'left' } }
            margin="small"
            dropContent={
                <Box pad="medium"
                    background="ligth-3"
                    elevation="small"
                    align="center"
                >
                    <Text size="small">{ header }</Text>
                    <RangeInput
                        value={ value }
                        min={ min } max={ max }
                        onChange={ onChange }
                        step={ step }
                    />
                    <Text weight="bold">{ value }</Text>
                    <Text weight="normal">{ unit }</Text>

                </Box>
            } />
    )
}

const FeaturesButton = ( { label,features,onChange } ) =>
{
    const FeaturesList = ( { features,onChange } ) => (
        <>
            { features.map( ( item,idx ) => (
            <CheckBox
                key={ item.name }
                label={ item.name }
                checked={ item.checked }
                onChange={ e => onChange( e,idx ) } />) 
                )
            }
        </>
    )



    return (
        <DropButton
            label={ label }
            dropAlign={ { top: 'bottom',left: 'left' } }
            margin="small"
            dropContent={
                <Box pad="medium"
                    background="ligth-3"
                    elevation="small"
                    align="start"
                    direction="column"
                    gap="small"
                >
                    <FeaturesList 
                        features={features} 
                        onChange={onChange} />

                </Box>
            } />
    )
}


const destApp = () =>
{

    const [ windStrength,setWindStrength ] = useState( null )
    const [ windFrequency,setWindFrequency ] = useState( null )
    const [ cost,setCost ] = useState( null )

    const date = new Date()
    const [ month,setMonth ] = useState( date.getMonth() )

    const [ listFeatures,setListFeatures ] = useState( [
        {
            name: 'Butter flat water',
            checked: false,
        },
        {
            name: 'Moderately flat water',
            checked: false,
        },
        {
            name: '1-2m Waves',
            checked: false,
        },
        {
            name: '2m+ Waves',
            checked: false,
        },
        {
            name: 'Beginer Friendly',
            checked: false,
        },
        {
            name: 'Kite-in-kite-out',
            checked: false,
        },
        {
            name: 'Nightlife',
            checked: false,
        }

    ] )
    const months = [ 'January','February','March','April','May','June','July','August','September','October','November','December' ];

    const updateFeaturesList = ( e,idx ) =>
    {

        listFeatures[ idx ].checked = e.target.checked
        const newFeatures = listFeatures
        setListFeatures( newFeatures )
        console.log( "Updated features list",newFeatures,e.target.checked )
    }

    return (
        <Grid rows={ [ "xsmall","fill" ] }
            areas={ [ [ "filterBar" ],[ "results" ] ] }
            gap="xxsmall">
            <Box gridArea="filterBar"
                direction="row-responsive"
                gap="xsmall"
                pad="xsmall"
                justify="center" >
                <CalButton label={ months[ month ].toLowerCase() } onSelect={ ( data ) => console.log( data ) } />
                <RangeButton
                    label="wind strength"
                    header="What's your wind preference?"
                    min="15"
                    max="45"
                    unit="kts"
                    value={ windStrength }
                    step={ 1 }
                    onChange={ ( e ) =>
                    {
                        setWindStrength( e.target.value )
                        console.log( windStrength )
                    } } />
                <RangeButton
                    label="wind frequency"
                    header="How often does your destination need to be windy?"
                    min="1"
                    max="7"
                    unit="days/week"
                    value={ windFrequency }
                    step={ 1 }
                    onChange={ ( e ) =>
                    {
                        setWindFrequency( e.target.value )
                        console.log( windFrequency )
                    } } />
                <RangeButton
                    label="cost"
                    header="Average daily cost: 1 lunch, diner and doubble room at a midrange hotel?"
                    min="10"
                    max="400"
                    unit="€"
                    value={ cost }
                    step={ 1 }
                    onChange={ ( e ) =>
                    {
                        setCost( e.target.value )
                        console.log( cost )
                    } } />

                <FeaturesButton
                    label="important features "
                    features={ listFeatures }
                    onChange={ updateFeaturesList }
                />
            </Box>
            <Box gridArea="results"
                margin="">
                Results go in here!

            </Box>


        </Grid>

    )
}

export default destApp 

The problem is in updateFeaturesList, you are mutating the state directly in this line listFeatures[ idx ].checked = e.target.checked, the state reference stay the same and so react does not know if it should re-render.

What you can do is copy the state, before changing it :

const updateFeaturesList = ( e,idx ) =>
{

    const newFeatures = [...listFeatures];
    newFeatures[ idx ].checked = e.target.checked
    setListFeatures( newFeatures )
    console.log( "Updated features list",newFeatures,e.target.checked )
}

You're mutating the original state in your updateFeaturesList function. Use the functional form of setState to update your current feature list:

const updateFeaturesList = (e, idx) => {
  const { checked } = e.target;
  setListFeatures(features => {
    return features.map((feature, index) => {
      if (id === index) {
        feature = { ...feature, checked };
      }

      return feature;
    });
  });
};

Also note that calling console.log("Updated features list", newFeatures,e.target.checked) immediately after setting the state won't show the updated state, since setting state is async.