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>');
}