This package has been deprecated

Author message:

use package 'reasync' instead

react-simple-async

0.4.0 • Public • Published

react-simple-async

Universal library for fetching react dependencies

Installation

npm i -S react-simple-async

How does it work?

On server, we use renderProps from react-router match callback. We iterate over components, looking after components decorated with asyncData

On client we use AsyncHandler component in react-router render, where we bind to componentWillMount to check data after startup and then componentWillReceiveProps to check for route changing

We don't do any optimisations, as we can do that on connected component, which receive in decorated function all it needs, like location, params, dispatch, getState

Example

On client

 
import React from 'react';
import ReactDOM from 'react-dom';
import createHistory from 'history/lib/createBrowserHistory';
import {createStore} from 'redux';
import reducers from './reducers'; //custom reducers
import {getRoutes} from './routes'; //custom routes
import {Provider} from 'react-redux';
import {Router, browserHistory } from 'react-router';
import {AsyncHandler} from 'react-simple-async';
 
const store = createStore();
const routes = getRoutes(store);
const mountPoint = document.getElementById('content');
 
const custom = {
  getState:store.getState,
  dispatch:store.dispatch
}
 
ReactDOM.render(
  (
    <Router
      history={browserHistory}
      routes={routes}
      render={(props) => <AsyncHandler custom={custom} {...props}/>}
    />
  ), mountPoint
);
 

On server

 
... //import createStore, getRoutes, reducers etc.
import {match} from 'react-router';
import createHistory from 'history/lib/createMemoryHistory';
import {getDataDependencies} from 'react-simple-async';
 
match({history,routes,location:req.originalUrl},(error, redirectLocation, renderProps) => {
  if (redirectLocation) {
    res.redirect(redirectLocation.pathname + redirectLocation.search);
  } else if (error) {
    console.error('ROUTER ERROR:', error);
    res.status(500);
    hydrateOnClient(); // error in router, you should try to hydrate app on client
  } else if(renderProps) {
 
      //here starts our work, we get all connected promises and after they are resolved, we render app for client
      Promise.all(getDataDependencies(renderProps.components)(store,renderProps.location, renderProps.params))
        .then(
          ... //custom render method
        )
        .catch((e) => {
          console.error(e);
          hydrateOnClient();
        });
 
  } else {
    console.error(err);
    res.status(404);  // page not found in router, you should try to hydrate app on client
    hydrateOnClient();
  }
})
 

Component decorator

For decorating component you can use default export. Decorator must contain function, which return promise. If you have more than one promises, wrap them in Promise.all

import asyncData from 'react-simple-async';
 
@asyncData(function({getState, dispatch}){ //available params, location and all keys defined in custom prop of AsyncHandler
  let promises = [];
  if(isSomethingFetched(getState())){ //check if you really need fetch
    promises.push(dispatch(fetchSomething())); //dispatch action
  }
  return Promise.all(promises);
})
export default class App extends Component {
...
 

Don't want to use decorators?

You can use same as above, only don't export class, but result of asyncData

  export default asyncData(function(){
    //fetch dependencies as above
  })(App); //exported component

Future?

  1. add full working example
  2. write tests

Readme

Keywords

none

Package Sidebar

Install

npm i react-simple-async

Weekly Downloads

1

Version

0.4.0

License

MIT

Last publish

Collaborators

  • svrcekmichal