1

I'm trying to create a simple React-Native MobX example-here's the working web example here

// App.tsx
const apiGetItems = async () => {
  return await new Promise(resolve => {
    resolve([
      {id: 1, title: 'eggs', quantity: 10},
      {id: 2, title: 'bread', quantity: 10},
      {id: 3, title: 'milk', quantity: 10},
      {id: 4, title: 'coffee', quantity: 10},
    ]);
  });
};

export const rootStore = createRootStore();

const App = (): JSX.Element => {
  useEffect(() => {
    apiGetItems()
        .then(rootStore.itemStore.setItems)
        .catch((err: Error) => {
          console.log('whoops!', err);
        });
  }, []);

  return (
    <>
      <SafeAreaView style={styles.container}>
        <View style={styles.item}>
          <ShoppingCart />
        </View>
        <View style={styles.item}>
          <ItemList />
        </View>
      </SafeAreaView>
    </>
  );
};

export {App};
// ItemStore.tsx
import {makeAutoObservable} from 'mobx';
import {type ItemShape, type ItemStoreShape} from '../interfaces';

export const ItemStore = (): ItemStoreShape => {
  return makeAutoObservable({
    items: [] as ItemShape[],
    setItems: function (vals: ItemShape[]) {
      this.items = vals;
    },
    getItems: function (): ItemShape[] {
      return this.items;
    },
    removeItem: function (id: number): void {
      console.log(`[ItemStore]:removeItem removing ${id}`);
      const it = this.items.find((item: ItemShape) => item.id === id);
      if (it !== undefined) {
        it.quantity--;
      }
      console.log(this.items);
    },
    addItem: function (id: number) {
      console.log(`[ItemStore]:addItem adding ${id}`);
      const it = this.items.find((item: ItemShape) => item.id === id);
      if (it !== undefined) {
        it.quantity++;
      }
      console.log(this.items);
    },
  });
};
// ItemList.tsx
import React from 'react';
import {ItemShape, type RootStoreShape} from '../interfaces';
import {observer} from 'mobx-react-lite';

import {rootStore} from '../../App';
import {Button, FlatList, Text} from 'react-native';

export const ItemList = observer((): JSX.Element => {
  const {itemStore, cartStore}: RootStoreShape = rootStore;

  const addItemToCart = (itemIndex: number, itemTitle: string): void => {
    itemStore.removeItem(itemIndex);
    cartStore.addItem(itemIndex, itemTitle);
  };

  const renderItemsNative = (): JSX.Element => {
    if (itemStore.items.length === 0) {
      return <></>;
    }

    const _renderItem = (item: ItemShape) => (
      <Text>
        ( {item.id} ) {item.title} - {item.quantity}
        <Button
          title={'✅'}
          onPress={() => addItemToCart(item.id, item.title)}
        />
      </Text>
    );

    return (
      <FlatList
        data={itemStore.items}
        renderItem={({item}) => _renderItem(item)}
      />
    );
  };

  return (
    <>
      <Text>Item List</Text>
      {renderItemsNative()}
    </>
  );
});

I have added logs and can see that the state is changing, but the components are not being re-rendered with new values.

I'm trying to do this using all functional code (no classes, no decorators, etc). Here's the gitHub repo (seems too big to paste here).

But, basically, on clicking the green checkmark button in the "Item List", the item quantity decrements, the item is added to the "Shopping Cart", but the new quantity isn't being shown in the "Item List"

Here's some logs

 LOG  [ItemStore]:removeItem removing 1
 LOG  [{"id": 1, "quantity": 9, "title": "eggs"}, {"id": 2, "quantity": 10, "title": "bread"}, {"id": 3, "quantity": 10, "title": "milk"}, {"id": 4, "quantity": 10, "title": "coffee"}]
 LOG  [CartStore]:addItem 1-eggs
 LOG  [{"id": 1, "quantity": 1, "title": "eggs"}]

// click button a second time
 LOG  [ItemStore]:removeItem removing 1
 LOG  [{"id": 1, "quantity": 8, "title": "eggs"}, {"id": 2, "quantity": 10, "title": "bread"}, {"id": 3, "quantity": 10, "title": "milk"}, {"id": 4, "quantity": 10, "title": "coffee"}]
 LOG  [CartStore]:addItem 1-eggs
 LOG  [{"id": 1, "quantity": 2, "title": "eggs"}]

I don't know if I'm missing something to make the state re-render or what, but, I'm lost and could use any help

Danila
  • 15,606
  • 2
  • 35
  • 67
Kearney Taaffe
  • 647
  • 8
  • 20
  • Can you paste the smallest example from the code here? SO frowns on links to code because they change, disappear, etc. Check out [mcve] – Abe Apr 15 '23 at 00:17
  • It seems that your example is working now, do you still need help? If not, you can probably close your question. – Danila Apr 24 '23 at 10:47
  • @Danila yeah, I still need help. I cannot get the item count to change on screen, but when I print out the store values the item count decrements – Kearney Taaffe Apr 25 '23 at 13:11

0 Answers0