Search code examples
react-nativemobxmobx-reactreact-native-ui-kitten

MobX observable changes not updating components


I have a store in MobX that handles containing the cart, and adding items to it. However, when that data is updated the components don't re-render to suit the changes. I tried using useEffect to set the total price, however when the cartData changes, the state is not updated. It does work on mount, though.

In another component, I call addItemToCart, and the console.warn function returns the proper data - but that data doesn't seem to be synced to the component. clearCart also seems to not work.

My stores are contained in one RootStore.

import React, {useState, useEffect} from 'react';
import {List, Text} from '@ui-kitten/components';
import {CartItem} from '_molecules/CartItem';
import {inject, observer} from 'mobx-react';

const CartList = (props) => {
    const {cartData} = props.store.cartStore;
    const [totalPrice, setTotalPrice] = useState(0);

    const renderCartItem = ({item, index}) => (
        <CartItem itemData={item} key={index} />
    );

    useEffect(() => {
        setTotalPrice(cartData.reduce((a, v) => a + v.price * v.quantity, 0));
        console.warn('cart changed!');
    }, [cartData]);

    return (
        <>
            <List
                data={cartData}
                renderItem={renderCartItem}
                style={{backgroundColor: null, width: '100%'}}
            />
            <Text style={{textAlign: 'right'}} category={'s1'}>
                {`Total $${totalPrice}`}
            </Text>
        </>
    );
};

export default inject('store')(observer(CartList));
import {decorate, observable, action} from 'mobx';

class CartStore {
    cartData = [];

    addItemToCart = (itemData) => {
        this.cartData.push({
            title: itemData.title,
            price: itemData.price,
            quantity: 1,
            id: itemData.id,
        });
        console.warn(this.cartData);
    };

    clearCart = () => {
        this.cartData = [];
    };

}


decorate(CartStore, {
    cartData: observable,
    addItemToCart: action,
    clearCart: action,
});

export default new CartStore();

Solution

  • I have solved the issue by replacing my addItemToCart action in my CartStore with this:

        addItemToCart = (itemData) => {
            this.cartData = [
                ...this.cartData,
                {
                    title: itemData.title,
                    price: itemData.price,
                    quantity: 1,
                    id: itemData.id,
                },
            ];
            console.warn(this.cartData);
        };