1

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

Tomitom
  • 63
  • 5
  • Could you show more code regarding the part where you modify the state? – Akash Jun 11 '21 at 13:58
  • 1
    Redux state should not be mutated. `nextState = {...state}` should solve your issue https://redux.js.org/faq/immutable-data https://stackoverflow.com/a/48819216/5793132 If you really want to mutate state, you should not use redux, instead use mobX https://mobx.js.org/the-gist-of-mobx.html – Ugur Eren Jun 11 '21 at 14:02
  • @UğurEren OP could use immer or redux toolkit as well, or just write code that doesn't mutate. – HMR Jun 11 '21 at 14:15
  • Using immer still creates immutable object. I gave mobx option as an alternative if op `really` wants to use mutations and it's advantages and disadvantages. But you are also correct, by using immer op can just write mutable code in his reducer, but outcome would still be immutable – Ugur Eren Jun 11 '21 at 14:32

1 Answers1

0

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,
          }
    ),
  },
};
HMR
  • 37,593
  • 24
  • 91
  • 160
  • Thank you so much ! I didn't know how to do that and your answer was perfect. Thank you again :) – Tomitom Jun 11 '21 at 15:13
  • @Tomitom Immutable update patterns can be found [here](https://redux.js.org/recipes/structuring-reducers/immutable-update-patterns) – HMR Jun 11 '21 at 15:32