{"id":20562250,"url":"https://github.com/benkingcode/react-data-fetching-components","last_synced_at":"2025-04-14T14:24:05.694Z","repository":{"id":65483141,"uuid":"117706348","full_name":"benkingcode/react-data-fetching-components","owner":"benkingcode","description":"♻️ Asynchronously load data for your React components with SSR","archived":false,"fork":false,"pushed_at":"2018-04-23T09:29:00.000Z","size":66,"stargazers_count":13,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-04-25T05:22:34.063Z","etag":null,"topics":["async","code-splitting","data","loading","react","server-side-rendering","ssr"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/benkingcode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-01-16T16:03:55.000Z","updated_at":"2020-06-29T03:37:09.000Z","dependencies_parsed_at":"2023-01-25T16:46:41.936Z","dependency_job_id":null,"html_url":"https://github.com/benkingcode/react-data-fetching-components","commit_stats":null,"previous_names":["dbbk/react-data-fetching-components"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benkingcode%2Freact-data-fetching-components","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benkingcode%2Freact-data-fetching-components/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benkingcode%2Freact-data-fetching-components/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benkingcode%2Freact-data-fetching-components/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/benkingcode","download_url":"https://codeload.github.com/benkingcode/react-data-fetching-components/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248895411,"owners_count":21179232,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async","code-splitting","data","loading","react","server-side-rendering","ssr"],"created_at":"2024-11-16T04:10:18.471Z","updated_at":"2025-04-14T14:24:05.666Z","avatar_url":"https://github.com/benkingcode.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"This package allows you to add a `getInitialData` method to your React components, no matter how deeply they are nested. It also works seamlessly with Server-Side Rendering and rehydration.\n\n# Installation\n\n`yarn add react-data-fetching-components`\n\n# Usage\n\nWrap any components you want to fetch data for with the `withInitialData` HOC, and add a static method `getInitialData` to the class. This method should return a Promise, or be set to an async function. Here's an example component;\n\n```jsx\nimport React, { Component } from 'react';\nimport { withInitialData } from 'react-data-fetching-components';\n\nclass Page extends Component {\n  static async getInitialData(props) {\n    const res = await fetch('...');\n    const json = await res.json();\n\n    return json;\n  }\n\n  render() {\n    return \u003cdiv\u003e{this.props.data}\u003c/div\u003e;\n  }\n}\n\nexport default withInitialData(Page);\n```\n\n## Loading and Error States\n\nYou can also add `loading` and `error` methods on your component, alongside `render`, that will display when `getInitialData` is either pending or rejects. For example;\n\n```jsx\nimport React, { Component } from 'react';\nimport { withInitialData } from 'react-data-fetching-components';\n\nclass Page extends Component {\n  static async getInitialData(props) {\n    const res = await fetch('...');\n    const json = await res.json();\n\n    return json;\n  }\n\n  loading() {\n    return \u003cdiv\u003eLoading data...\u003c/div\u003e;\n  }\n\n  error() {\n    return \u003cdiv\u003eError loading data!\u003c/div\u003e;\n  }\n\n  render() {\n    return \u003cdiv\u003e{this.props.data}\u003c/div\u003e;\n  }\n}\n\nexport default withInitialData(Page);\n```\n\n## Server-Side Rendering\n\n### Setup\n\nTo get SSR working, you just need to edit two files. First, edit your `server.js` file by awaiting on `getAllInitialData` before rendering your top-level app component. Then, when you're ready to `renderToString`, wrap the app component with `\u003cComponentDataStore data={data}\u003e` to pass in the data that has been pre-fetched. It should look something like this pseudocode;\n\n```jsx\nimport {\n  ComponentDataStore,\n  getAllInitialData\n} from 'react-data-fetching-components';\n\nserver.get('/*', async (req, res) =\u003e {\n  const app = \u003cApp /\u003e;\n\n  const data = await getAllInitialData(app);\n\n  const markup = renderToString(\n    \u003cComponentDataStore data={data}\u003e{app}\u003c/ComponentDataStore\u003e\n  );\n\n  res.status(200).send(`\u003chtml\u003e\n    \u003cbody\u003e\n      ${markup}\n    \u003c/body\u003e\n  \u003c/html\u003e`);\n});\n```\n\nThen, in your HTML response, you should add the following script tag before your JS assets;\n\n```jsx\n\u003cscript\u003ewindow._COMPONENT_DATA_ = ${JSON.stringify(data)};\u003c/script\u003e\n```\n\nNow, edit your `client.js` file by adding the `\u003cComponentDataStore\u003e` component and passing in the data from `window._COMPONENT_DATA_` like so;\n\n```jsx\nimport { ComponentDataStore } from 'react-data-fetching-components';\n\nconst data = window._COMPONENT_DATA_;\n\nhydrate(\n  \u003cComponentDataStore data={data}\u003e\n    \u003cApp /\u003e\n  \u003c/ComponentDataStore\u003e,\n  document.getElementById('root')\n);\n```\n\nThis allows the client-side app to seamlessly rehydrate the data loaded during your server request.\n\n### Advanced: Parallelising Network Requests\n\nBy default, every time you server-render a component that has `getInitialData`, rendering is paused until that method's Promise is completed. This means that `this.props.data` is always available by the time the `render` method is fired. However, if you have a lot of nested components making network requests, your page load times will start to get noticeably slower, as every request is happening sequentially. Fortunately, there's a solution! Here's an example component;\n\n```jsx\nclass ParallelComponent extends Component {\n  static getInitialDataInParallel = true;\n\n  static async getInitialData(props) {\n    const res = await fetch('...');\n    const json = await res.json();\n\n    return json;\n  }\n\n  render() {\n    return \u003cdiv\u003e{this.props.data ? this.props.data : null}\u003c/div\u003e;\n  }\n}\n```\n\nBy setting the `getInitialDataInParallel` property on your component class to `true`, during the server-render pass the `getInitialData` Promise will be pushed to an array and later fired in parallel with `Promise.all`. The main caveat for your component is that now, in your `render` method, you must include a conditional check for `this.props.data`, as it will not be defined during the initial render pass.\n\nThis is ideal for cases where you have a nested component that makes a data request, but does not depend upon the result of a data request higher up the component tree, e.g. it can rely purely on routing params.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenkingcode%2Freact-data-fetching-components","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenkingcode%2Freact-data-fetching-components","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenkingcode%2Freact-data-fetching-components/lists"}