title: Mobx Autorun in practice
body: <p>I'm trying to get Mobx's autorun to work correctly.</p>
  
  <p>My use case is I have one model that I like to serialize (or dehydrate) when it is changed and add that information to another model's data. This brings me rudimentary time travel of model states. Both are observables.</p>
  
  <p>Edit: Idea in model separation is that one is app's data model and other should be completely separate library that I could use from the app. I need to track changes in the app regularly, but show UI for the state tool on the same page.</p>
  
  <p>Now, autorun seems to make its own inferences of what I'm actually tracking. When I moved the model instance inside observing model's instantiation, autorun wasn't called anymore when changes happened. When model instance was created on the module top level, it worked as I expected. This was when I only changed one property of observing model (the one that gets changed by every autorun call). When I tried changing two things at once in the observing model, autorun was now called for these changes also,  leading to a unending cycle (which Mobx caught).</p>
  
  <p>I'd like to know how to express what I'm tracking with autorun function be more explicit, or wether there are other ways to keep track of model changes and update other model when anything happens.</p>
  
  <hr>
  
  <p>Edit with code example.</p>
  
  <p>This is what I did (greatly simplified):</p>
  
  <pre><code>class DataModel {
      @observable one_state = null;
  }
  
  class StateStore {
      @observable states = [];
  }
  
  let data = new DataModel();
  let store = new StateStore();
  
  autorun(() =&gt; {
     store.states.push(data.one_state);
     console.log("new data", toJSON(store.states));
  });
  
  data.one_state = "change 1";
  data.one_state = "change 2";
  </code></pre>
  
  <p>And this creates circular dependency because autorun gets called for <strong>both</strong> original data model change and the resulting store change, whilst I'm only interested in tracking changes to the former.</p>
  
  <hr>
  
  <p>Edit with working result:</p>
  
  <pre><code>class DataModel {
      @observable one_state = null;
  }
  
  class StateStore {
      @observable states = asFlat([]);
  }
  
  let data = new DataModel();
  let store = new StateStore();
  
  autorun(() =&gt; {
     store.states.push(data.one_state);
  });
  
  data.one_state = "change 1";
  data.one_state = "change 2";
  </code></pre>
  
  <p>As per @mweststrate answer, using asFlat with store's states variable and removing the logging from autorun broke the problem cycle.</p>