React SSR Data Loader
This library will help with declarative data loading in React - with full server side rendering support!
Why?
When you need to load data on the server, transfer it to the client and hydrate it Server Side Rendering becomes a lot more difficult. Many libraries which currently solve this problem are all in (e.g. Next.JS). Our goal was to make a standalone solution that can be dropped into an existing project.
Getting started
These steps show how you would load a blog post using the data loader.
DataLoaderResources
1. Create a
This is the entry point to the library, you can register resources
(types of data you want to load).
2. Register a resource
// TypeScript /** Register the resource **/// Generic arguments are specifying the data type & the load arguments// The function parameters are the resource type (should be unique for each resource), and a function to load the data // JavaScript
3. Use the Data loader component
// Wrap your application in a DataProvider, passing your resources
That's it, the data loader will take care of loading the data when the params change automatically.
Server side rendering
To enable server side rendering there are a few components. The implementation will change depending on how you are doing your server side rendering, the data loader exposes events to enable it to work with most other libraries.
1. Tracking data loads
This is just one way you could do this, but this approach has worked pretty well for us.
// This object contains a promise, and ways to trigger completion. if loadTriggered // Return the rendered result and the loaded server state to the client// This example doesn't include wrapping the rendered markup with the full index.html // NOTE: we are using the serialiseJavascript library, because it handles a bunch of scenarios JSON.stringify doesn'tres.send`<script>window.INITIAL_STATE = </script><div id="root"></div>`
2. Hydrate on the client
The hard part is done, to hydrate on the client we just pass the INITIAL_STATE to the DataProvider
React.hydrate , document.getElementById'root',
This will hydrate your app with all the data that was loaded on the server into the client.
How it works
When you register resources
they return a DataLoader, a fully type-safe React component which allows you to get at that data type.
You can load multiple DataLoaders in a single page. Each DataLoader
will fetch the resource once, sharing the data between data-loaders when the parameters match.
The DataProvider
component is responsible for fetching the data. When DataLoader
s are mounted they register with the data provider so it can notify the DataLoader
s when any relevant data is updated. This means DataLoaders only re-render when the data they are interested in is updated.
Params hashing
Behind the scenes the data loader uses a library called hash-sum
to create hashes of the parameter object. You can control which of the data loader params are taken into account by specifying the cache keys (similar to React hooks).
You can override the hashing function on the DataProvider if you have issues with the inbuilt library.
More info
General approaches to data loading in SSR
There are two main approaches for loading data with server side rendering
- Walk the React component tree and allow components to statically declare what data they need. The server can then load the data before rendering. This approach is not really idiomatic React because it breaks encapsulation
- Perform the SSR, then track any data loading requests which are triggered. Once complete, do another SSR with the data loaded.