5.0.2 • Published 3 years ago

@cra-express/router-prefetcher v5.0.2

Weekly downloads
1
License
MIT
Repository
-
Last release
3 years ago

@cra-express/router-prefetcher

Simple utility to map your routes and prefetch your data on server

Instead of using this, you might want to wait for React Suspense, demo

:warning: Alpha stage. API may change, don't use on production yet!

Prerequisites

  • React Router with array config
  • Promise support

Start

npm i @cra-express/router-prefetcher

Setup and Usage

  • Add {{SCRIPT}} to public/index.html
<div id="root"></div>
{{SCRIPT}}
// server/app.js

import { createReactAppExpress } from '@cra-express/core';
import { getInitialData } from '@cra-express/router-prefetcher';
import routes from '../src/routes';
const path = require('path');
const React = require('react');
const { StaticRouter } = require('react-router');

const { default: App } = require('../src/App');
const clientBuildPath = path.resolve(__dirname, '../client');
let AppClass = App;
let serverData;
const app = createReactAppExpress({
  clientBuildPath,
  universalRender: handleUniversalRender,
  onEndReplace(html) {
    const state = store.getState();
    return html.replace(
      '{{SCRIPT}}',
      `<script>
        window.__INITIAL_DATA__ = ${JSON.stringify(serverData).replace(
          /</g,
          '\\u003c'
        )};
      </script>`
    );
  }
});

function handleUniversalRender(req, res) {
  const context = {};
  return getInitialData(req, res, routes)
    .then(data => {
      serverData = data;
      const app = (
        <StaticRouter location={req.url} context={context}>
          <AppClass routes={routes} initialData={data} />
        </StaticRouter>
      );
      return app;
    })
    .catch(err => {
      console.error(err);
      res.send(500);
    });
}

export default app;
// src/index.js

import routes from './routes';

const data = window.__INITIAL_DATA__;
ReactDOM.hydrate(
  <BrowserRouter>
    <App routes={routes} initialData={data} />
  </BrowserRouter>,
  document.getElementById('root')
);
// src/App.js

import React from 'react';
import { Route, Switch } from 'react-router';

const App = ({ routes, initialData }) => {
  return (
    <Switch>
      {routes.map((route, index) => {
        return (
          <Route
            key={index}
            path={route.path}
            exact={route.exact}
            render={props =>
              React.createElement(route.component, {
                ...props,
                routes: route.routes,
                initialData: initialData[index] || null
              })
            }
          />
        );
      })}
    </Switch>
  );
};
// src/routes/DemoPage/AboutView.js

import React from 'react';

import withSSR from '../../components/withSSR';

class AboutView extends React.Component {
  static getInitialData({ match, req, res }) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({
          article: `
This text is ALSO server rendered if and only if it's the initial render.
          `,
          currentRoute: match.pathname
        });
      }, 500);
    });
  }

  render() {
    const { isLoading, article, error } = this.props;
    return (
      <div>
        <h1>About</h1>
        {isLoading && <div>Loading from client...</div>}
        {error && <div>{JSON.stringify(error, null, 2)}</div>}
        {article && <div>{article}</div>}
      </div>
    );
  }
}

export default withSSR(AboutView);

Please get the withSSR code here

License

MIT

5.0.2

3 years ago

5.0.1

3 years ago

5.0.0

3 years ago

4.3.2

5 years ago

4.3.1

6 years ago

4.3.0

6 years ago

4.2.1

6 years ago

4.2.0

7 years ago

4.1.0

7 years ago

4.0.1

7 years ago

4.0.0

7 years ago

4.0.0-alpha.3

7 years ago