0.0.2-development β€’ Published 4 years ago

data-hoc v0.0.2-development

Weekly downloads
6
License
MIT
Repository
github
Last release
4 years ago

npm.io

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 :heart: 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!

1.0.4

5 years ago

1.0.3

5 years ago

1.0.2

5 years ago

1.0.1

5 years ago

1.0.0

5 years ago

0.0.0-alpha.1

5 years ago

1.0.0-alpha.0

5 years ago