Git Product home page Git Product logo

hydrate-promises's Introduction

Hydrating React component state from promises

Consider a rather trivial component which fetches data from some endpoints, to render some content.

Sure, there's Flux, Relay/GraphQL and what have you.

But perhaps this is for a prototype, and we want a "quick and dirty" opininated means of hydrating our state.

So we introduce a mixin for hydrateFromPromises which we can use as follows:

var FrontPage = React.createClass({
   mixins: [ HydrateFromPromisesMixin ],
   getInitialState: function () {
      return {};
   },   
   componentDidMount: function () {
      log.info('componentDidMount');
      this.hydrateFromPromises({
         frontpageArticles: function() {
            return getPromise('/feed/Frontpage');
         },
         popularArticles: function() {
            return getPromise('/feed/Popular');
         }
      });
   },
   render: function () {
      if (!this.state.frontpageArticles) {
         log.info('render initial');
         return false;
      } else {
         log.info('render hydrated', this.state.frontpageArticles.length, 
            this.state.popularArticles.length);
      }
      return ( // JSX 
         ... 
      );
   }
});

where frontpageArticles and popularArticles are to be properties of state. For these we specify a function which returns an ES6 Promise for the data to be loaded.

In this example, we use an ordinary getPromise utility function to perform a cacheable XMLHttpRequest and return a Promise as follows:

export function getPromise(url) {
   if (cache[url]) {
      var data = cache[url];
      if (data._time)  {
         if (new Date().getTime() - data._time < config.cacheExpirySeconds*1000) {
            return Promise.resolve(data);
         }
      } else {
         return Promise.resolve(data);
      }
   }
   return new Promise((resolve, reject) => {
      var req = new XMLHttpRequest();
      req.onload = function () {
         if (req.status !== 200) {
            reject({message: 'status ' + req.status});
         } else {
            var data = JSON.parse(req.response);
            data._time = new Date().getTime();
            cache[url] = data;
            resolve(data);
         }
      };
      req.open('GET', url);
      req.send();
      log.debug('loadJSON', url);
   });
}

Finally, our mixin utility hydrates our component state as follows:

var HydrateFromPromisesMixin = {
   hydrateFromPromises: function(promises) {
      log.debug('hydrate', Object.keys(promises));
      let that = this;
      let count = 0;
      function set(key, data) {
         that.state[key] = data;
         count += 1;
         if (count === Object.keys(promises).length) {
            log.debug('hydrate resolved');
            that.setState(that.state);
         }
      }
      Object.keys(promises).forEach(key => {
         log.info('hydrate promise', key);
         promises[key]().then(data => {
            log.debug('hydrate promise resolved', key);
            set(key, data);
         }, function(error) {
            log.debug('hydrate promise rejected', key, error);
            set(key, null);
         });
      });
   }
};

module.exports = HydrateFromPromisesMixin;

where we invoke our promise producers, and only invoke setState when all the promises have been resolved.

https://twitter.com/evanxsummers

hydrate-promises's People

Contributors

evanx avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.