Search code examples
javascriptreact-nativereduxreact-reduxredux-reducers

Component don't re-render after redux modification


I'm using redux in my app and at first, it works as I want. When I add something into my state through the reducer, my component is re-rendering as I want. But when I only modify the value of a property inside the state, my component isn't re-rending.

If you need code I can upload it (or some parts) but I think that the problem is more of the way of thinking.

Exemple of my state

state = {
    "BaliseSeen": {
        "Marseille": [
            {
                "id": "5566",
                "nom": "Notre dame de La Garde",
                "type": "Monument",
                "vue": true,
            },
        ],
        "Toulon": [
            {
                "id": "1122",
                "nom": "Isen Yncrea Méditerranée",
                "type": "Monument",
                "vue": true,
            },
            {
                "id": "3344",
                "nom": "Appartement n°69",
                "type": "Monument",
                "vue": true,
            },
            {
                "id": "6677",
                "nom": "Mairie",
                "type": "Info",
                "vue": false,
            },
        ],
    },
    "Medailles": [
        {
            "ville": "Toulon",
        },
    ],
    "User": [],

}

When I add something new like that, it work and re-rendered :

nextState = {...state,
      BaliseSeen: {
               ...state.BaliseSeen, [city]: [...state.BaliseSeen[city], { id: action.value.id, type: action.value.type, nom: action.value.nom, vue: action.value.vue }]
      }
}

But when I want to only change the property vue from false to true like that, it work (when I check the state in the app the modification is applied but my component isn't re-rendered :

BaliseSeenIndex = state.BaliseSeen[city].findIndex(item => item.id === action.value.id)
nextState = state
nextState.BaliseSeen[city][BaliseSeenIndex].vue = true

(I also tried to delete the element from my state and add it after, but same as before, it work without render my component) So I don't know how to say that the state is modified


Solution

  • As commented; you should not mutate, do the following instead

    //not sure where cityp comes from but I assume it is from the action
    return {
      ...state,
      BaliseSeen: {
        ...state.BaliseSeen,
        [city]: state.BaliseSeen[city].map((item) =>
          item.id !== action.value.id
            ? item//not the item we want to edit, return unchanged
            : {//item we are looking for, return changed copy
                ...item,
                vue: true,
              }
        ),
      },
    };