omniscientjs / immstruct

Immutable data structures with history for top-to-bottom properties in component based libraries like React. Based on Immutable.js
374 stars 21 forks source link

next-animation-frame event for reference cursor? #40

Closed singggum3b closed 9 years ago

singggum3b commented 9 years ago

Currently reference object missing observe for next-animation-frame event ?

dashed commented 9 years ago

Do you really want to do this?

swap event for observed references doesn't use the same semantics as structure.on('swap').

next-animation-frame exists for the purpose that React.render is executed with respect to animation frames.

At the moment, all functions are called with swap event: https://github.com/omniscientjs/immstruct/blob/0c55b617459d59947d706641aba3a542448b46a7/src/structure.js#L40-L47


If you'd like you can send a PR to refactor the following to be able to add next-animation-frame event for observed references (see example below): https://github.com/omniscientjs/immstruct/blob/0c55b617459d59947d706641aba3a542448b46a7/src/structure.js#L196-L211

One application of observed references is to tie cursor changes to this.forceUpdate(); for a component. You can batch these changes to requestAnimationFrame. For example:

var possiblyEmitAnimationFrameEvent = function (newFn) {
  var queuedChange = false;
  if (typeof requestAnimationFrame !== 'function') {
    return function () {};
  }

  return function requestAnimationFrameEmitter (newStructure, oldData, keyPath) {
    if (queuedChange) return;
    queuedChange = true;

    requestAnimationFrame(function () {
      queuedChange = false;
      newFn(newStructure, oldData, keyPath);
    });
  };
};

function forceUpdateOn (ref) {
  var bound;
  return {
    componentDidMount: function () {

      bound = ref.observe(possiblyEmitAnimationFrameEvent(_ => this.forceUpdate()));

    },
    componentWillUnmount: function () {
      bound();
    }
  };
}
mikaelbr commented 9 years ago

I don't think it makes sense to have this in core, but you could probably extend the behaviour in your code to only emit on animation frame. Feel free to re-open the issue if there is something else.