Skip to content

React higher order components for data fetching and server side rendering.

License

Notifications You must be signed in to change notification settings

rphansen91/data-hoc

Repository files navigation

styled with prettier Travis Coveralls Greenkeeper badge Dev Dependencies npm downloads

A set of react providers and components that allows for data to be used as a component, whether on the server or on the client.

Example App

Install

yarn add data-hoc

Features

  • Async Loader Higher Order Components
  • Opt In Server Side Rendering

Loading Data

You can import the generated bundle to use the whole library generated by this starter:

import React from 'react';
import { AsyncHoc } from 'data-hoc';

export const fetchJediQuery = (i) => fetch(`https://swapi.co/api/people/${i}/?schema=json`).then((res) => res.json());

export const FetchJedis = ({ params = {} }) => (
    <AsyncHOC
        name="FetchJedis"
        params={params}
        query={(ids) => Promise.all(ids.map(fetchJediQuery))}
    >
        {({ loading, error, data }) => <DisplayJedis jedis={data} />}
    </AsyncHOC>
);

Server Side Rendering

Example Here

// /server/index.js
import express from 'express';
import universalLoader from './universal';

const app = express();
const PORT = process.env.PORT || 8081;

app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.resolve(__dirname, '../build'), { index: false }));
app.use('*', universalLoader);

app.listen(PORT, () => {
  console.log(`App listening on port ${PORT}!`);
});
// /server/universal.js
import path from 'path';
import fs from 'fs';
import React from 'react';
import { StaticRouter } from 'react-router-dom';
import { SSRDataProvider, createSSRDataClient, renderToStringWithData } from 'data-hoc';
import App from '../src/App';

const filePath = path.resolve(__dirname, '../build/index.html');
const htmlData = fs.readFileSync(filePath, 'utf8');
const prepHTML = (html, { body, state }) => {
  return html.replace('</head>', `<script>window.__SSR_DATA__=${JSON.stringify(state).replace(/</g, '\\u003c')}</script></head>`)
  .replace(/<div id="root">.*<\/div>/, `<div id="root">${body}</div>`)
};

const universalLoader = (req, res) => {
  const context = {}
  const client = createSSRDataClient({}, { ssr: true });
  const ServerApp = () => (
    <SSRDataProvider value={client}>
      <StaticRouter location={req.originalUrl} context={context}>
        <App />
      </StaticRouter>
    </SSRDataProvider>
  );
  
  renderToStringWithData(client, ServerApp);
  .then((body) => {
    if (context.url) {
      return res.redirect(301, context.url);
    }
    
    const state = client.extract();
    const html = prepHTML(htmlData, {
      state,
      body
    });

    res.send(html);
  })
  .catch(e => {
    res.send(htmlData);
  });

};

export default universalLoader;
// /src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { SSRDataProvider, createSSRDataClient } from 'data-hoc';
import App from './App';

const initial = window.__SSR_DATA__ || {};
const client = createSSRDataClient(initial);

ReactDOM.render(
    <SSRDataProvider value={client}>
        <BrowserRouter>
            <App />
        </BrowserRouter>
    </SSRDataProvider>
    , document.getElementById('root'));

Credits

Made with ❀️ by @rphansen91 and all these wonderful contributors (emoji key):


Ciro

πŸ’» πŸ”§

Marius Schulz

πŸ“–

Alexander Odell

πŸ“–

Ryan Ham

πŸ’»

Chi

πŸ’» πŸ”§ πŸ“–

Matt Mazzola

πŸ’» πŸ”§

Sergii Lischuk

πŸ’»

Steve Lee

πŸ”§

Flavio Corpa

πŸ’»

Dom

πŸ”§

Alex Coles

πŸ“–

David Khourshid

πŸ”§

AarΓ³n GarcΓ­a HervΓ‘s

πŸ“–

Jonathan Hart

πŸ’»

Sanjiv Lobo

πŸ“–

Stefan Aleksovski

πŸ’»

dev.peerapong

πŸ’»

Aaron Groome

πŸ“–

Aaron Reisman

πŸ’»

kid-sk

πŸ“–

Andrea Gottardi

πŸ“–

Yogendra Sharma

πŸ“–

Rayan Salhab

πŸ’»

This project follows the all-contributors specification. Contributions of any kind are welcome!

About

React higher order components for data fetching and server side rendering.

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published