4

I have a react functional component that accesses the MobX store with useContext. I have found two ways to observe an array that is an observable from the store. First, the useObserver hook and wrapping the component with observer.

I thought that these are the same but that the useObserver only observes specific properties (such as the array that is passed) but I am experiencing a problem when the array reaches size 2 and then the component does not re-render. That's the case when using useObserver. When wrapping with observer, this is fixed.

Can anyone explain why this is happening and what's the difference?

const ApplesContainer = observer(() => {
    const stores = useStores();
    const applesArray = stores.fruits.apples;

    return (
            {applesArray.map(apple => (
                <Apple key={apple.id} apple={apple} />
            ))}
    );
});

// OR with useObserver()

function useGlobalState() {
    const stores = useStores();
    return useObserver(() => ({
        applesArray: stores.fruits.apples
    }));
}
const ApplesContainer = observer(() => {
    const { applesArray } = useGlobalState();

    return (
            {applesArray.map(apple => (
                <Apple key={apple.id} apple={apple} />
            ))}
    );
});
KubiGR
  • 41
  • 3
  • did you follow [this link](https://mobx-react.js.org/recipes-context)? – armin yahya Jan 08 '21 at 13:09
  • I have read the migration guide (although I am still at mobx 5.x). Still I do not understand what's the difference. Is it the destructuring wrong? – KubiGR Jan 08 '21 at 13:29
  • you mean migration from 5 to 6? Official Documentation has not mentioned useObserver – armin yahya Jan 08 '21 at 13:41
  • The useObserver is mentioned in the migration guide, as a tool to destructure data and maintain reactivity. I know that wrapping with the observer works but I do not understand why the useObserver hook does not when the observable array reaches 3 items. – KubiGR Jan 08 '21 at 13:59
  • The link in the top comment is dead. Would be nice to see an updated answer to this now that useObserver is deprecated. – Jeffrey Tillwick Dec 14 '22 at 20:32
  • The link was pointing to the old and deprecated mobx documentation, where the useObserver was also mentioned. I cannot find that site so I guess they took it down. There is no alternative source of useObserver at the current documentation. I don't really have a concrete answer but you can also view here a more "official" reply about the differences, from the mobx discussion I created [link](https://github.com/mobxjs/mobx/discussions/2709) – KubiGR Dec 17 '22 at 16:15

1 Answers1

1

useObserver must return JSX with an observable value. This hook takes care of tracking changes and re-rendering them. If no observable value exists in JSX, then it won't be re-rendered.

e.g.:

const SomeContainer =() => {
    const { someStores } = useStores();

    return useObserver(()=>(
            {someStore.data.map(val => (
                <Apple key={val.id} val={val} />
            ))}
    ));
};
tdy
  • 36,675
  • 19
  • 86
  • 83
JogaBonito
  • 21
  • 4