marko-js / marko

A declarative, HTML-based language that makes building web apps fun
https://markojs.com/
MIT License
13.28k stars 641 forks source link

Discussion on support for mobx state management #1265

Closed cameronbraid closed 3 years ago

cameronbraid commented 5 years ago

I have been using mobx for state management with markojs for a few months in production and its been a great combination of technologies - https://www.drivenow.com.au

I can write code like the following:

Store.ts

import { observable } from "mobx"
class AppStore {
   @observable value = 0
   increment() {
    this.value++
   }

}

export const Store = new AppStore()

View.marko

import { Store } from "./Store"
class {
  mobxObservable{}()

  increment() {
    Store.increment()
  }
}
<div>value is ${Store.value} <button on-click('increment')>+</button></div>

And it will automatically re-render when increment is called. Infact any component that has a reference to the Store instance that renders its value attribute will also be re-rendered.

To achieve this I had to patch marko as follows https://github.com/marko-js/marko/commit/33ac015d88967eec8e1ccec10253e2fe3a5fa225

You can see form the above that components need to be tagged using code like mobxObservable{}() as the patch (mobx-helper.js defineComponent) uses the existence of this method in order to handle the component specially.

So two hooks are require in marko as defined in the mobx-helper.js

Is there any way that marko could expose these hooks in a generic way so that there is no need to patch marko ?

As a second question, Ideally I would like to use code like observable{} in following instead of mobxObservable{}()

View.marko

import { Store } from "./Store"
observable {}
class {
  increment() {
    Store.increment()
  }
}
<div>value is ${Store.value} <button on-click('increment')>+</button></div>

however there doesn't seem to be a way in marko to use a transformer to augment the component class

cameronbraid commented 5 years ago

There are some tests in https://github.com/cameronbraid/marko/commit/1784ce933602f8b8958c691308dc657701c9a427

DylanPiercey commented 3 years ago

Although this is something that I think is worth having in userland I don't think there is anything needed from Marko core to support this. The <context> tag may come in handy for userland implementations.