Search code examples
reactjsmobxmobx-react

Why the list doesn't re-render after updating the store?


I started learning mobx and got stuck. Why when I change listItems, List doesn't re-render?

I have store:

export const listStore = () => {
    return makeObservable(
        {
            listItems: [],
            addItem(text) {
                this.listItems.push(text);
            }
        },
        {
            listItems: observable,
            addItem: action.bound
        }
    );
};

Component that adds text from input to store:

const store = listStore();

export const ListForm = observer(() => {
    const [value, setValue] = useState();

    return (
        <>
            <input type="text" onChange={e => setValue(e.target.value)} />
            <button onClick={() => store.addItem(value)}>Add note</button>
        </>
    );
});

And I have a list component:

const store = listStore();

export const List = () => {
    return (
        <React.Fragment>
            <ul>
                <Observer>
                    {() => store.listItems.map(item => {
                        return <li key={item}>{item}</li>;
                    }
                </Observer>
            </ul>
            <ListForm />
        </React.Fragment>
    );
};

I don't understand what's wrong. Looks like the list doesn't watch the store changing

codesandbox: https://codesandbox.io/s/ancient-firefly-lkh3e?file=/src/ListForm.jsx


Solution

  • You create 2 different instances of the store, they don't share data between. Just create one singleton instance, like that:

    import { makeObservable, observable, action } from 'mobx';
    
    const createListStore = () => {
      return makeObservable(
        {
          listItems: [],
          addItem(text) {
            this.listItems.push(text);
          }
        },
        {
          listItems: observable,
          addItem: action.bound
        }
      );
    };
    
    export const store = createListStore();
    

    Working example