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-suspense-fetch

v0.6.0

Published

A low-level library for React Suspense for Data Fetching

Downloads

1,441

Readme

react-suspense-fetch

CI npm size discord

A low-level library for React Suspense for Data Fetching

Introduction

React 18 comes with Suspense (sort of), but Suspense for Data Fetching is left for data frameworks. The goal of this library is to provide a thin API to allow Suspense For Data Fetching without richer frameworks.

Project status: Waiting more feedbacks before finalizing the API.

Install

npm install react-suspense-fetch

Usage

import React, { Suspense, useState, useTransition } from 'react';
import { createRoot } from 'react-dom/client';

import { createFetchStore } from 'react-suspense-fetch';

// 1️⃣
// Create a store with an async function.
// The async function can take one input argument.
// The input value becomes the "key" of cache.
// By default, keys are compared with strict equal `===`.
const store = createFetchStore(async (userId) => {
  const res = await fetch(`https://reqres.in/api/users/${userId}?delay=3`);
  const data = await res.json();
  return data;
});

// 2️⃣
// Prefetch data for the initial data.
// We should prefetch data before getting the result.
// In this example, it's done at module level, which might not be ideal.
// Some initialization function would be a good place.
// We could do it in render function of a component close to root in the tree.
store.prefetch('1');

// 3️⃣
// When updating, wrap with startTransition to lower the priority.
const DisplayData = ({ result, update }) => {
  const [isPending, startTransition] = useTransition();
  const onClick = () => {
    startTransition(() => {
      update('2');
    });
  };
  return (
    <div>
      <div>First Name: {result.data.first_name}</div>
      <button type="button" onClick={onClick}>Refetch user 2</button>
      {isPending && 'Pending...'}
    </div>
  );
};

// 4️⃣
// We should prefetch new data in an event handler.
const Main = () => {
  const [id, setId] = useState('1');
  const result = store.get(id);
  const update = (nextId) => {
    store.prefetch(nextId);
    setId(nextId);
  };
  return <DisplayData result={result} update={update} />;
};

// 5️⃣
// Suspense boundary is required somewhere in the tree.
// We can have many Suspense components at different levels.
const App = () => (
  <Suspense fallback={<span>Loading...</span>}>
    <Main />
  </Suspense>
);

createRoot(document.getElementById('app')).render(<App />);

API

FetchStore

fetch store

prefetch will start fetching. get will return a result or throw a promise when a result is not ready. preset will set a result without fetching. evict will remove a result. abort will cancel fetching.

There are three cache types:

  • WeakMap: input has to be an object in this case
  • Map: you need to call evict to remove from cache
  • Map with areEqual: you can specify a custom comparator

Type: {prefetch: function (input: Input): void, get: function (input: Input, option: GetOptions): Result, preset: function (input: Input, result: Result): void, evict: function (input: Input): void, abort: function (input: Input): void}

Properties

  • prefetch function (input: Input): void
  • get function (input: Input, option: GetOptions): Result
  • preset function (input: Input, result: Result): void
  • evict function (input: Input): void
  • abort function (input: Input): void

createFetchStore

create fetch store

Parameters

  • fetchFunc FetchFunc<Result, Input>
  • cacheType CacheType<Input>?
  • presets Iterable<any>?

Examples

import { createFetchStore } from 'react-suspense-fetch';

const fetchFunc = async (userId) => (await fetch(`https://reqres.in/api/users/${userId}?delay=3`)).json();
const store = createFetchStore(fetchFunc);
store.prefetch('1');

Examples

The examples folder contains working examples. You can run one of them with

PORT=8080 npm run examples:01_minimal

and open http://localhost:8080 in your web browser.

You can also try them in codesandbox.io: 01 02 03 04 05 06 07

Blogs