reactjsmobx

my code using mobx doesn't update the state


I have a simple code, I'm new to mobx, its easier in context but I had to use mobx :

import { makeAutoObservable } from "mobx";
import booksRepository from "../Books/Books.repository";

class BookStore {
  books = [];
  showPrivateBooks = false;

  constructor() {
    makeAutoObservable(this);
  }

  async loadBooks() {
    const books = await booksRepository.getBooks(this.showPrivateBooks);
    this.books = [...books];
  }

  async addBook(newBook) {
    await booksRepository.addBook(newBook);
    await this.loadBooks();
  }

  async toggleShowPrivateBooks() {
    this.showPrivateBooks = !this.showPrivateBooks;
    await this.loadBooks();
  }
}

const bookStore = new BookStore();
export default bookStore;

and the index.js:

import React, { useEffect } from "react";
import ReactDOM from "react-dom";
import { observer } from "mobx-react";
import bookStore from "./Store/BookStore";

import "./styles.css";

function App() {
  useEffect(() => {
    bookStore.loadBooks();
  }, []);

  const handleAddBook = async () => {
    const newBook = {
      name: "Book",
      ownerId: "postnikov",
      author: "Someone",
    };
    await bookStore.addBook(newBook);
  };

  return (
    <div>
      <div>
        <button onClick={() => bookStore.toggleShowPrivateBooks()}>
          {bookStore.showPrivateBooks ? "Show All Books" : "Show Private Books"}
        </button>
      </div>
      {bookStore.books.map((book, i) => (
        <div key={i}>
          {book.author}: {book.name}
        </div>
      ))}
      <button onClick={handleAddBook}>Add</button>
    </div>
  );
}

const ObservedApp = App;

const rootElement = document.getElementById("root");
ReactDOM.render(<ObservedApp />, rootElement);


but, the toggle button doesn't work.

It looks like the store is updating but the data on the screen doesn't change Once I press the button, the store updates, and new data is loaded but the UI does not change

you can find the full code here codesandbox


Solution

  • You need to wrap your App (and basically every component that uses any data from MobX store) with observer HOC:

    import { observer } from "mobx-react";
    
    const App = observer(...)
    

    https://mobx.js.org/react-integration.html#react-integration