Mobx with Haxe

Hi, did anyone start to work on a haxe implementation or externs to work with/ like Mobx?
https://medium.com/@mweststrate/becoming-fully-reactive-an-in-depth-explanation-of-mobservable-55995262a254

Thereā€™s a similar way of handling state in pure haxe: GitHub - haxetink/tink_state: Handle those pesky states.

Interesting!

I used mobx a fair bit at my last job and really liked the way it checked which observables are used in a render function, and so would re-render whenever one of them changes. It looks like Observable.auto is pretty much the magic needed to achieve the same thing.

It would be cool to see someone demonstrate this working with React in a similar way to MobX.

@axelhuizinga If you want to use real mobx (not just something similar) I think your best bet would be to read the documentation for using MobX with ES5 rather than ES6, and then use those functions to wrap your Haxe objects. I probably wouldnā€™t bother with fancy externs. As far as Haxe is concerned MyType might as well be the same as Observable<MyType>, as it generates exactly the same code and mobx does itā€™s thing under the hood. You just need to figure out where to put the extendObservable calls etc.

If you manage to get it working Iā€™d love to hear about it! MobX is a very clever framework and I prefer it to Redux etc, so would be cool to see it work with Haxe.

Just starting to learn react I will need some time to get my head around it - a pure haxe way would seem to be preferable to me if itā€™s possible to implement and maintain all the compelling points MobX has including the Mobx-state-tree.
How would I have to translate the example from https://github.com/mobxjs/mobx-state-tree/blob/master/docs/getting-started.md about the ability of MobX to emit granular updates into a solution with tink_state?

const TodoView = observer(props =>
    <div>
        <input type="checkbox" checked={props.todo.done} onChange={e => props.todo.toggle()} />
        <input type="text" value={props.todo.name} onChange={e => props.todo.setName(e.target.value)} />
    </div>)

const AppView = observer(props =>


<button onClick={e => props.store.addTodo(randomId(), ā€˜New Taskā€™)}>Add Task
{props.store.todos.values().map(todo => )}

)

Another point Iā€™d like to see your comments about is the rule:

You donā€™t need react router. As I said before you want your stores to represent your applicationā€™s state. When you let react router handle part of your application state, you donā€™t let your stores represent the application state. So keep your current displayed view in a property in one of your stores. Then you have one component that just renders what the property says.

found at
https://medium.com/dailyjs/mobx-react-best-practices-17e01cec4140

const TodoView = observer(props =>
    <div>
        <input type="checkbox" checked={props.todo.done} onChange={e => props.todo.toggle()} />
        <input type="text" value={props.todo.name} onChange={e => props.todo.setName(e.target.value)} />
    </div>)

Would be in Haxe:

// observed functional component (static function)
class TodoView {
    static var observed = Mobx.observer(render);
    static function render(props) {
        return jsx('
            <div>
                <input type="checkbox" 
                    checked={props.todo.done} 
                    onChange={function(e) props.todo.toggle()} />
                <input type="text" 
                    value={props.todo.name} 
                    onChange={function(e) props.todo.setName(e.target.value)} />
            </div>
        ');
    }
}

// observed class
class TodoView {
    static var observed = Mobx.observer(TodoView);
    function render() {
        return jsx('
            <div>
                <input type="checkbox" 
                    checked={props.todo.done} 
                    onChange={function(e) props.todo.toggle()} />
                <input type="text" 
                    value={props.todo.name} 
                    onChange={function(e) props.todo.setName(e.target.value)} />
            </div>
        ');
    }
}

// usage
return jsx('<TodoView.observed/>');

Using haxe-react from master there is a :jsxStatic meta to make the usage ā€œnicerā€:

@:jsxStatic('observed')
class TodoView {
    static var observed = Mobx.observer(TodoView);
    function render(props) {...}
}

// less verbose usage
return jsx('<TodoView/>');
1 Like

Did you or anyone write Mobx externs already?

I didnā€™t - using redux for now, but mobx looks nice as well.

One more question - how will I have to translate this function parameters (last lines) into valid haxe syntax?

 const localeStore = new LocaleStore("en", translations);
 
 const store = {
     locale: localeStore, // The locale store has to be called locale. 
 };
 
 const _Home = ({intl: {formatMessage}, locale}) => <div>
     <h1>{formatMessage({id: "hello"})}</h1>

ā€¦

This is called ā€œdestructuringā€.

typedef HomeProps = {
  intl: {formatMessage: Dynamic->Void},
  locale: LocaleStore
}
static function Home(props: HomeProps) {
  var formatMessage = props.intl.formatMessage;
  var locale = props.locale;
  return jsx('<div>
     <h1>{formatMessage({id: "hello"})}</h1>
  </div>');
}