npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-ssr-data-provider

v0.1.1

Published

Type-safe isomorphic data provider to conveniently optimise data fetching during server-side and client-side rendering.

Downloads

8

Readme

react-ssr-data-provider

This library is still in PoC stage, and it's not ready for production. Feel free to share your ideas. If you want to contribute. Please keep your pull requests small, and understandable.

Type-safe isomorphic data provider to conveniently optimise data fetching during server-side and client-side rendering.

NPM JavaScript Style Guide Build and Deploy

Install

yarn add react-ssr-data-provider

or

npm install --save react-ssr-data-provider

Usage

First, create your DataProvider:

MyDataProvider.tsx

import { getDataProvider, DataClientBase } from 'react-ssr-data-provider';

/* Create your DataClient interface. This ensures ssr and csr data 
 * providers are returning the same shape of data */
export interface MyDataClient extends DataClientBase {
  getGreeting: (name: string) => Promise<string>;
}

/* - DataProvider: A higher-order component to provider a data 
 * context for your component tree
 * - useDataClient: react hook to get access to the data provider 
 * client
 * Name these as you like for exports so they fit your projects 
 * naming conventions */
export const { 
  DataProvider: MyDataProvider,
  useDataClient: useMyDataClient 
} = getDataProvider<MyDataClient>();

Set it up for the browser:

client.tsx

import React from 'react';
import ReactDOM from 'react-dom';
import { MyDataProvider } from './MyDataProvider';

/* Wrap your application with your DataProvider and define the 
 * functions that fetch data from the browser, e.g.: calling a 
 * public API*/
ReactDOM.hydrate(
  <MyDataProvider 
    providers={{ 
      getGreeting: (name) => Promise.resolve(
        `Hello ${name} from the client side. 
         I'm probably doing an http call or using a proxy to fetch data.`
      ) 
    }}
  >
    <App />
  </MyDataProvider>,
  document.getElementById('root')
);

Set it up for server-side rendering:

server.tsx

import React from 'react';
import express from 'express';
import { renderToString } from 'react-dom/server';
import { MyDataProvider } from 'MyDataProvider';
import { DataContext } from 'react-ssr-data-provider';
import App from './App';

const app = express();

app.get('*', async (req, res) => {
  const myDataContext = {} as DataContext;
  /* Wrap your application with your DataProvider and define 
   * the functions that fetch data during server-side rendering,
   * e.g.: calling a microservoce direcly within the VPC network */
  const renderedApp = renderToString(<MyDataProvider 
    dataContext={myDataContext} 
    providers={{ 
      getGreeting: (name) => Promise.resolve(
        `Hello ${name} from the server side. 
         I'm probably doing an internal service or database call without going through the internet.`
         ) 
     }}
   >
    <App />
  </MyDataProvider>);

  /* dataContext.getScript() will return a string, containing a 
   * <script></script> that you need to inject into your HTML, 
   * so the client-side DataProvider can use the pre-fetched data 
   * from the server. This will make your first client-side data 
   * fetches lighning fast. */
  const dataScript = myDataContext.getScript ? await myDataContext.getScript() : '';

  res.send(`<!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    <body>
      ${renderedApp}
      ${dataScript}
      <script src="/myBundle.js"></script>
    </body>
  </html>`);
});

app.listen(3000, () => console.log('App is listening on port 3000'));

Use the isomorphic data providers in your App

App.tsx

import React from 'react';
import { useMyDataClient } from './MyDataProvider';
import { useDataEffect } from 'react-ssr-data-provider';

const App: React.FC = () => {
  /* You can get access to your data provider methods using the 
   * `useDataClient()` hook. They will use the pre-fetched data 
   * from the server-side for the first render. */
  const { getGreeting } = useMyDataClient();
  const [greeting, setGreeting] = useState<string>();

  const update = useCallback(async () => {
    /* First call to getGreeting will use the pre-fetched data.
     * Any subsequent call will use the client-side data provider. */
     setGreeting(await getGreeting('FooBar'));
  }, [setGreeting, getGreeting]);

  useDataEffect(() => {
    update();
  }, [getGreeting]);

  return <div>
    {greeting}
    <button onClick={update}>Fetch data again</button>
  </div>;
};

Upcoming features

  • withDataClient() higher-order component
  • withDataProvider() higher-order component
  • Use suspense for full server-side rendering as soon as it's available in react
  • provide way to describe the client interface without TypeScript
  • use web workers for client-side fetching
  • use worker threads for server-side fetching
  • do you have an idea? Let me know about it on github!

License

MIT © sleepingevil