0.3.1 • Published 5 years ago

react-router-store v0.3.1

Weekly downloads
11
License
MIT
Repository
github
Last release
5 years ago

Installation

npm install react-router-store

react-router-store makes the react-router processing simpler for server side rendering.

Usage

Create async and sync route stores

// asyncRouteStore.ts
import { RouteStore, AsyncRouteStore } from 'react-router-store';

export const asyncRouteStore: RouteStore = new AsyncRouteStore([
  {
    path: '/',
    exact: true,
    component: () => import('./pages/main'),
  },
  {
    path: '/sample',
    component: () => import('./pages/sample'),
  },
]);
// syncRouteStore.ts
import { RouteStore, SyncRouteStore } from 'react-router-store';

import main from './pages/main';
import sample from './pages/sample'; 

export const syncRouteStore: RouteStore = new SyncRouteStore([
  {
      path: '/',
      exact: true,
      component: main,
    },
    {
      path: '/sample',
      component: sample,
    },
]);

Add <Route/>

// main.tsx
import React from 'react';
import { RouteStore, Suspense } from 'react-router-store';
import { BrowserRouter, Route, Link, Switch } from 'react-router-dom';

interface MainProps {
  routeStore: RouteStore;
}

function LoadingMessage() {
  return <div>Loading...</div>;
}

export function Main({ routeStore }: MainProps) {
  return (
    <div id="layout">
      <ul id="navigation">
        <li>
          <Link to="/">Home</Link>
        </li>
        <li>
          <Link to="/sample">Home</Link>
        </li>
      </ul>
      
      <div id="content">
        <Suspense fallback={<LoadingMessage/>}>
          <Switch>
            {/*<Route exact path="/" component={}/>*/}
            {/*<Route path="/sample" component={}/>*/}
            {routeStore.getAllRoutes()}
          </Switch>
        </Suspense>
      </div>
    </div>
  )
}

Creates entry files

Creates entry files for client and server.

// client.tsx
import React from 'react';
import { hydrate, render } from 'react-dom';
import { BrowserRouter, Route, Link } from 'react-router-dom';

import { asyncRouteStore } from './asyncRouteStore';
import { Main } from './main';

function App() {
  return (
    <BrowserRouter>
      <Main routeStore={asyncRouteStore}/>
    </BrowserRouter>
  )
}

if (window.__INITIAL_STATE__) {
  asyncRouteStore.preload(location.pathname).then(() => {
    hydrate(<App/>, document.querySelector('#app'));
  });
} else {
  render(<App/>, document.querySelector('#app'));
}

For client, preloads the route component before running the app.

// server.tsx
import React from 'react';
import { StaticRouter } from 'react-router';
import express, { Express, Request, Response } from 'express';
import { renderToString } from 'react-dom/server';

import { syncRouteStore } from './syncRouteStore';
import { Main } from './main';

function renderHtml(url: string, initialState: object): string {
  const htmlText: string = renderToString(
    <StaticRouter location={url} context={{}}>
      <Main routeStore={syncRouteStore}/>
    </StaticRouter>
  );
  
  return `
    <html>
      <head>
        <meta charset=UTF-8>
        <script>
          window.__INITIAL_STATE__ = ${initialState.replace(/</g, '\\u003c')};
        </script>
      </head>
      <body>
        <div id="app">${htmlText}</div>
      </body>
    </html>
  `;
}

const app: Express = express();

app.get('/', (req: Request, res: Response) => {
  res.send(renderHtml(req.url, {}));
});

app.get('/sample', (req: Request, res: Response) => {
  res.send(renderHtml(req.url, {}));
});

app.listen(8080);

Add a test

Add a test to make sure both stores are set to the same options.

import { compareRouteOptions } from 'react-router-store';
import { asyncRouteStore } from './asyncRouteStore';
import { syncRouteStore } from './syncRouteStore';

describe('/route', () => {
  it('Should be matched all route options of stores', () => {
    expect(compareRouteOptions(
      asyncRouteStore.getRouteOptions(),
      syncRouteStore.getRouteOptions(),
    )).toBeTruthy();
  });
});
0.3.1

5 years ago

0.3.0

5 years ago

0.2.0

5 years ago

0.1.2

5 years ago

0.1.1

5 years ago

0.1.0

5 years ago