npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-collider

v1.10.5

Published

Express middleware for isomorphic express + react apps

Downloads

67

Readme

React-collider Build Status

Express middleware for isomorphic Express + React apps. Also usable for any NodeJs app without Express.

Check out the example folder for a working example, including data-fetching from the Dailymotion API.

Features

  • Handle server and client side rendering
  • First call is done server side, subsequent calls use only api
  • Takes care of data fetching when needed
  • Possibility to serve your app by a cdn
  • Data fetching is done at the component level
  • Seo ready

Installation

$ npm install --save react-collider

Usage

Server side

Simply add the server middleware in your express app, giving your routes as argument.

import express  from 'express'
import collider from 'react-collider/server'
import routes   from './routing'

var app  = express(),
    port = process.env.PORT || 3000

app.use(collider(routes))

app.listen(port, () => {
    console.log('Listening on 127.0.0.1:' + port)
})

Logging

You can have informations in a log file:

// logs to react-collider.log
app.use(collider(routes, {log: true}))

// logs to a custom file path
app.use(collider(routes, {log: path.join(__dirname, 'server.log')}))

Client side

Similar: call the client module with your routes.

import collider from 'react-collider/client'
import routes   from './routing'

collider(routes)

Components

If your component must fetch some data before being rendered, use a fetchData static method. It must return an object or an array of objects with expose, url and params keys. Expose is the name under which the data will be available.

The fetchData method will receive an argument being the params from the router.

Example of a simple component:

export default class Home extends React.Component {
    static fetchData(params) {
        return {
            expose: 'home-data',
            url: `https://api.dailymotion.com/video/${params.videoId}`
        }
    }
    render() {
        var videos = getVideoList(this.props.data['home-data'])

        return (
            <div>
                <h1>Homepage</h1>
                {videos}
            </div>
        )
    }
}

When your component includes another component which needs data too, define a getDependencies static method to return an array of components:

import Sidebar from './sidebar'
import Footer  from './footer'

export default class Home extends React.Component {
    static getDependencies() {
        return [Sidebar, Footer]
    }
    render() {
        return (
            <div>
                <Sidebar data={this.props.data.Sidebar} />
                <div>
                    <h1>Homepage</h1>
                </div>
                <Footer data={this.props.data.Footer} />
            </div>
        )
    }
}

Data Provider

The dataProvider module allows data fetching from a url or from the initial data fetched server-side.

###dataProvider(component, url, options)

  • expose String. The name under which the data will be available
  • url Url to call
  • options Object. Available options:
    • once: Removes the data from the local variable after use. This means the next time you call the same data it will fetch them remotely. Default to true.
    • forceFetch: Fetches the data remotely even if the data are available locally. Default to false.
    • set: Sets the data locally after fetching them remotely. The next time you need them they will be taken locally (unless you use the forceFetch option). Default to false.
import provider from 'react-collider/dataProvider'

class Video extends React.Component {
    componentDidMount() {
        var data = provider('video', `https://api.dailymotion.com/video/${params.id}?fields=id,title`, {once: true})
    }
}

Client side app only

If your servers are down and you can't pre-render the pages server-side, your app will still work client side (assuming your API is okay). All you need is to send a basic html file with your app bundled. Check out the example folder for an example.

Usage without Express

You can use react-collider wihtout express. You can simply use it to get the React component to render and the data to use:

import collider from 'react-collider'
import routes   from './routing'

var url = '/video'

// simply provide your routes and the url
collider(routes, url, null, (Handler, data) => {
    var page = React.renderToString(React.createElement(Handler, {data: data}))
})

Custom data fetching

By default the module runs every fetchData methods of the components. If you need to handle yourself the data fetching you can pass a custom module that will receive an array of components needing to fetch data. It must return a promise.

You can use a custom fetch handler for server as well as client side. You can obviously choose to use a custom fetch handler server side but not client side (or the opposite), or a different one.

var routes   = require('./routing'),
    customFetchHandler = require('./fetch-handler')

// server side
app.use(collider(routes), {fetch: customFetchHandler})

// or client side
collider(routes, {fetch: customFetchHandler})
// Custom fetch handler
var Promise = require('bluebird')

module.exports = function fetchHandler(components, params) {
    return new Promise(function(resolve) {
        var dataSet = {}

        components.forEach(function(component) {
            // handle the data fetching the way you want
            // component.fetchData(params)
        })

        resolve(dataSet)
    })
}

You will be able to handle the components the way you want. Check out the default fetch handler to see an example.