Cristianjs19
Cristianjs19

Reputation: 863

Redux: global state of props it isn't updated in between tabs

In the project, the states of the props are managed globally with redux (redux-toolkit). So if I execute an action that modifies them, this should modify the global state and be taken in the rest of the tabs if I don't get it wrong. It turns out that only when I refresh each tab it just takes the changes in the props but not "automatically", what can be caused this??

I best describe how it happens:

For example I have 2 tabs open, one where I add items to the cart and the other the cart. If I have 2 items in the cart and I delete them from right here, then I add another one from the items tab, it happens that in this it is not registered that the items were deleted and it appears to me as if I had added a 3rd item. If I go to the car and refresh, I get 3 items "having been added again" which I removed. If I now delete these 3 from the cart, I go back to the previous one and refresh, there it takes that they were deleted, being able to add articles from 0.

Also I thought that the reducer could be wrong since if I execute "addItem" action it should modify directly the current state of prop but I can't see an error here. Anyway happens what I described before.

This is my reducer slice:

// cart slice:
import { createSlice } from '@reduxjs/toolkit'
 
export const initialState = {
  items: [],
  countItems: 0,
 }
 
const cartSlice = createSlice({
  name: 'cart',
  initialState,
  reducers: {
    addItem: (state, action) => {
      const product = action.payload
      const itemExists = state.items.find((item) => product.id === item.id)
      if (itemExists) {
        itemExists.quantity += 1
      } else {
        const newProduct = { ...product, ...{ quantity: 1 } }
        state.items.push(newProduct)
      }
      state.countItems += 1
     
    },
    removeItem: (state, action) => {
      const product = action.payload
      state.items = state.items.filter((item) => product.id !== item.id)
 
      state.countItems -= product.quantity
    },
  },
})
 
export const {
  addItem,
  removeItem,
} = cartSlice.actions
export const cartSelector = (state) => state.cart
export default cartSlice.reducer

I would love any advice or hint about where I can find the mistake here, thanks in advance!

EDIT:
I'm using redux-persist to persist changes in store configured in root index.js as this:

import React from 'react'
import ReactDOM from 'react-dom'
import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit'
import { Provider } from 'react-redux'
import App from './App'
import persistedReducer from './slices'
import {
  persistStore,
  FLUSH,
  REHYDRATE,
  PAUSE,
  PERSIST,
  PURGE,
  REGISTER,
} from 'redux-persist'
import { PersistGate } from 'redux-persist/integration/react'

const store = configureStore({
  reducer: persistedReducer,
  middleware: getDefaultMiddleware({
    serializableCheck: {
      ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
    },
  }),
})
const persistor = persistStore(store)

ReactDOM.render(
  <Provider store={store}>
    <PersistGate loading={null} persistor={persistor}>
      <App />
    </PersistGate>
  </Provider>,
  document.getElementById('root')
)

Upvotes: 1

Views: 2359

Answers (1)

Pramod Mali
Pramod Mali

Reputation: 1808

Not sure much about redux-toolkit library much. But to accomplish syncing between tabs not possible without using a persistent storage or a library that uses persists the global state. Here are a few options for you:

  1. Using session/localstorage to store and retrieve your global state. This option requires you to set up your initial state whenever a new tab is being opened, along with serialization/deserialization (JSON.stringify() and JSON.parse()) is required.

  2. redux-persist. This library comes with a lot of features out of the box but at the same time, it requires a bit more configurations. It'll do serialization/deserialization on behalf of you. One of the main pain points is it's not updated frequently so may introduce a lot of vulnerabilities.

  3. Web workers (i.e. redux-state-sync library). Less configuration

  4. IndexDB (i.e. pouchdb and react-pouchdb) Example using pouchdb.

Here is a blog post that explains these in much more detail.

Upvotes: 4

Related Questions