component not re-rendering when updating an object with mobx

27 Views Asked by At

I'm starting with mobx and I'm trying to ensure that my view updates when I add a dashboard by pressing the add dashboard button, when I click on the button the function is called and seems to do this that I want however if I click again on the button looking at the size of the dashboard table I see that it has not changed and my view does not update whatever happens (except via the use of useState on the selectedDashboardIndex).

What am I doing wrong please?

DashboardStore class

export class DashboardStore {
  autoRefresh: number
  dashboards: Dashboard[]

  constructor() {
    makeObservable(this, {
      autoRefresh: observable,
      dashboards: observable,
      addDashboard: action
    })
    this.autoRefresh = 0
    this.dashboards = []
  }

  addDashboard(dashboard: Dashboard) {
    this.dashboards.push(dashboard)
  }
}

Dashboard class

 export class Dashboard {
  name: string
  items: DashboardItem[]

  constructor(name: string, items?: DashboardItem[]) {
    makeObservable(this, {
      name: observable,
      items: observable,
      addItem: action
    })
    this.name = name || ''
    this.items = items || []
  }

  addItem(item: DashboardItem) {
    this.items.push(item)
  }
}

Dashboard page:

const DashboardPage = observer(() => {
  const [selectedDashboardIndex, setSelectedDashboardIndex] = useState<number>(0)
  const dashboardStore = new DashboardStore()
  const dashboard = new Dashboard('Dashboard 1')
  dashboardStore.dashboards.push(dashboard)

  const onDelete = () => {}

  const onAddDashboard = () => {
    const nb = dashboardStore.dashboards.length + 1
    const newDashboard = new Dashboard(`${t('Dashboard')} ${nb}`)
    dashboardStore.addDashboard(newDashboard)
    setSelectedDashboardIndex(dashboardStore.dashboards.length - 1)
  }

  return (
    <>
      <section>
        <div>
          {dashboardStore.dashboards?.length > 0 &&
            dashboardStore.dashboards.map((dashboard: Dashboard, index: number) => {
              return (
                <button
                  key={'dashboardButton_' + index}}
                  onClick={() => {
                    setSelectedDashboardIndex(index)
                  }}
                >{dashboard.name}</button>
              )
            })}

          {dashboardStore.dashboards?.length > 0 && (
            <button
              onClickHandler={() => {
                onAddDashboard()
              }}
            ><AddIcon /></button>
          )}
        </div>
      </section>
      <section>
        {dashboardStore.dashboards?.length > 0 && (
          /* DASHBOARD CONTENT */
          <>{dashboardStore.dashboards[selectedDashboardIndex].name}</>
        )}
      </section>
    </>
  )
})

export default DashboardPage
0

There are 0 best solutions below