async-props-nfs

0.4.4 • Public • Published

AsyncProps for React Router

npm package #rackt on freenode

Co-located data loading for React Router apps. Data is loaded before the new screen renders. It is designed to be both a useful solution for many apps, as well as a reference implementation for integrating data with React Router (stuff like redux, relay, falcor etc).

Docs & Help

For questions and support, please visit our channel on Reactiflux or Stack Overflow. The issue tracker is exclusively for bug reports and feature requests.

Installation

Using npm:

$ npm install async-props

Then with a module bundler like webpack, use as you would anything else:

// using an ES6 transpiler, like babel
import AsyncProps from 'async-props'

The UMD build is also available on npmcdn:

<script src="https://npmcdn.com/async-props/umd/AsyncProps.min.js"></script>

You can find the library on window.AsyncProps.

Notes

This is pre-release, it's pretty close though. If you are using it then you are a contributor. Please add tests with all pull requests.

Usage

import { Router, Route } from 'react-router'
import AsyncProps from 'async-props'
import React from 'react'
import { render } from 'react-dom'
 
class App extends React.Component {
 
  // 1. define a `loadProps` static method
  static loadProps(params, cb) {
    cb(null, {
      tacos: [ 'Pollo', 'Carnitas' ]
    })
  }
 
  render() {
    // 2. access data as props :D
    const tacos = this.props.tacos
    return (
      <div>
        <ul>
          {tacos.map(taco => (
            <li>{taco}</li>
          ))}
        </ul>
      </div>
    )
  }
}
 
// 3. Render `Router` with AsyncProps middleware
render((
  <Router render={(props) => <AsyncProps {...props}/>}>
    <Route path="/" component={App}/>
  </Router>
), el)

Server

import { renderToString } from 'react-dom/server'
import { match, RoutingContext } from 'react-router'
import AsyncProps, { loadPropsOnServer } from 'async-props'
 
app.get('*', (req, res) => {
  match({ routes, location: req.url }, (err, redirect, renderProps) => {
 
    // 1. load the props
    loadPropsOnServer(renderProps, (err, asyncProps, scriptTag) => {
 
      // 2. use `AsyncProps` instead of `RoutingContext` and pass it
      //    `renderProps` and `asyncProps`
      const appHTML = renderToString(
        <AsyncProps {...renderProps} {...asyncProps} />
      )
 
      // 3. render the script tag into the server markup
      const html = createPage(appHTML, scriptTag)
      res.send(html)
    })
  })
})
 
function createPage(html, scriptTag) {
  return `
    <!doctype html>
    <html>
      <!-- etc. --->
      <body>
        <div id="app">${html}</div>
 
        <!-- its a string -->
        ${scriptTag}
      </body>
    </html>
  `
}

API

setCustomCreateScriptTagMethod

You can use custom createScriptTag(json) function to escape html symbols json for example. By default, AsyncProps use:

function createScriptTag(json){
  return `<script>__ASYNC_PROPS__ = ${json}</script>`
}

You can specify your own function:

import { setCreateScriptTagMethod } from 'async-props'
 
setCreateScriptTagMethod(function(json){
    return `<script>__ASYNC_PROPS__ = decodeURI(${encodeURI(json)})</script>`
})

As you see, you function should return '<script>__ASYNC_PROPS__ =' + some_json_with_optional_wrapping + '</script>'

setCustomStringifyPropsMethod

You can use custom stringifyProp(propsArray) function to minify json on production for example. By default, AsyncProps use:

function (propsArray){
  return JSON.stringify(propsArray, null, 2)
}

You can specify your own function:

import { setStringifyPropsMethod } from 'async-props'
 
setStringifyPropsMethod(function(propsArray){
    return JSON.stringify(propsArray)
})

As you see, you function should String, that you can parse on client.


Please refer to the example, as it exercises the entire API. Docs will come eventually :)

Readme

Keywords

Package Sidebar

Install

npm i async-props-nfs

Weekly Downloads

6

Version

0.4.4

License

MIT

Last publish

Collaborators

  • numminorihsf