https://github.com/estrattonbailey/react-hydrate
Generic data fetching, caching, and SSR hydration pattern for React
https://github.com/estrattonbailey/react-hydrate
async react react-ssr
Last synced: over 1 year ago
JSON representation
Generic data fetching, caching, and SSR hydration pattern for React
- Host: GitHub
- URL: https://github.com/estrattonbailey/react-hydrate
- Owner: estrattonbailey
- Created: 2017-06-19T19:52:05.000Z (about 9 years ago)
- Default Branch: master
- Last Pushed: 2017-08-22T00:11:11.000Z (almost 9 years ago)
- Last Synced: 2025-03-15T23:15:46.637Z (over 1 year ago)
- Topics: async, react, react-ssr
- Language: JavaScript
- Homepage:
- Size: 489 KB
- Stars: 31
- Watchers: 1
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# react-hydrate
Generic data fetching and SSR hydration pattern for React.
[](http://standardjs.com)
## Features & Goals
1. Co-locate data dependencies with your components
2. Supports infinitely nested loaders
3. Fetches requested data on the server and hydrates on the client for a fast startup
4. Wraps components so users can easily define loading states for components
5. Routing agnostic. **Works with `react-router` v4.**
6. Lightweight **~1.9kb**
Related: [react-hydrate-link](https://github.com/estrattonbailey/react-hydrate-link) - prefetch data for your next route using react-router v4.
## Usage
### Defining components
```javascript
/**
* Projects.js
*/
import api from 'my-api'
import { hydrate } from 'react-hydrate'
import Project from './Project.js'
export default hydrate(
/**
* dataLoader receives component props
* and any state already in the store
*/
(props, state) => {
return api.fetchProjects().then(projects => {
return {
projects: projects
}
})
},
/**
* mapStateToProps receives the
* loaded data via `state` and any
* component props.
*
* You should return `false` here if
* the data needed is not yet availabe.
* If a falsy value is returned, it
* tells the library that the loader
* hasn't been run yet or hasn't
* yet resolved.
*/
(state, props) => {
return state.projects ? {
projects: state.projects
} : false
}
)(({ loading, data, ...inheritedProps }) => {
/**
* Component is always passed a loading
* prop that represents the status of their
* dataLoader function
*/
return loading ? (
Loading data...
) : (
data.projects.map(project => )
)
})
```
```javascript
/**
* App.js
*/
import React from 'react'
import Projects from './Projects.js'
export default props => (
)
```
### Creating root app
```javascript
import React from 'react'
import { render } from 'react-dom'
import { BrowserRouter as Router } from 'react-router-dom'
import { Tap } from 'react-hydrate'
import App from './App'
render((
), document.getElementById('root'))
```
### Server
```javascript
import React from 'react'
import { renderToString } from 'react-dom/server'
import { StaticRouter: Router } from 'react-router'
import { Tap, createStore } from 'react-hydrate'
import { asyncRender } from 'react-hydrate/dist/server'
import App from './App.js'
app.use((req, res) => {
const ctx = {}
const store = createStore({})
const Root = (
)
asyncRender(Root).then(() => {
const state = store.getState()
const content = renderToString(Root)
if (ctx.url) {
res.writeHead(302, {
Location: ctx.url
})
res.end()
} else {
res.send(`
${content}
window.__hydrate = ${JSON.stringify(state)}
`)
res.end()
store.clearState()
}
})
})
```
## Dependencies
- [react-tree-walker:](https://github.com/ctrlplusb/react-tree-walker) Walk a React element tree. by [@ctrlplusb](https://github.com/ctrlplusb)
MIT License