Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

React Native Redux Component not rerendering on Redux State Change

I am working on a shopping basket component in React Native. The content and price of the basket get saved in the global redux store. When the user selects an item, an action gets dispatched to add the item to the basket and to update the total basket price.

The UI however does not get updated on this global state change.

My Reducer

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const INITIAL_STATE = {
basket: [],
basketPrice: 0,
};

const mainReducer = (state = INITIAL_STATE, action) => {
    const stateCpy = state;
    switch (action.type) {
        case 'SET_BASKET':
            stateCpy.basket = action.payload
            return stateCpy;
        case 'ADD_TO_BASKET':
            stateCpy.basket.push(action.payload)
            return stateCpy
        case 'REMOVE_FROM_BASKET':
            let tempItems = stateCpy.basket
            for (var x = 0; x < stateCpy.basket.length; x++) {
                if (stateCpy.basket[x]._id === action.payload) {
                    tempItems.splice(x, 1)
                    break;
                }
            }
            stateCpy.basket = tempItems
            return stateCpy
        case 'SET_BASKET_PRICE':
            stateCpy.basketPrice = action.payload
            console.log(stateCpy.basketPrice)
            return stateCpy
        default:
            return state
    }
};

export default mainReducer

My Actions

const setBasket = basket => ({
    type: 'SET_BASKET',
    payload: basket,
});
const addToBasket = item => ({
    type: 'ADD_TO_BASKET',
    payload: item,
});
const removeFromBasket = item_id => ({
    type: 'REMOVE_FROM_BASKET',
    payload: item_id,
});

const setBasketPrice = price => ({
    type: 'SET_BASKET_PRICE',
    payload: price,
});

export default actions = {
    setBasket,
    addToBasket,
    removeFromBasket,
    setBasketPrice
}

My UI Component

... 

import { useSelector, useDispatch } from 'react-redux'

export const RestaurantView = ({ navigation, route }) => {
    const basket = useSelector((state) => state.basket)
    const basketPrice = useSelector((state) => state.basketPrice)
    
    const dispatch = useDispatch()

...

function calcBasketPrice(){
        let tempBasketPrice = 0
        basket.forEach(element => {
            tempBasketPrice += element.price
        });
        return tempBasketPrice
        
    }

    function addToBasket(item) {
        dispatch(actions.setBasketPrice(calcBasketPrice() + item.price))
        dispatch(actions.addToBasket(item))
    }


return ( <View>
    <ItemCard onPress={addToBasket}> </ItemCard>
    <Text style={{ textAlign: "right", padding: 15, fontSize: 20 }}> {basketPrice}</Text>
</View>)

}

When logging the basketPrice to console in the reducer, it logs the correct, updated value on each press/dispatch but there no changes in the UI. When a local state change is made to force a rerender, it renders with the correct value from the global store.

>Solution :

Your stateCpy variable is actually not a copy, but just a reference to state – so your reducer is actually modifying the old redux state instead of creating a new one.

Since this is a very outdated style of Redux and in modern Redux createSlice reducers it is totally okay to modify state, I would recommend you not to fix this in legacy Redux, but to take a look at modern Redux – which is also less error-prone and about 1/4 of the code you would write with legacy Redux.
Rewriting your reducer is not a lot of work and in the long run you will really benefit from the (since 2019) new style.

Take a look at the official Redux tutorial

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading