Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Experimental] Support promises as fallback data #2891

Merged
merged 9 commits into from
Feb 16, 2024
Merged

[Experimental] Support promises as fallback data #2891

merged 9 commits into from
Feb 16, 2024

Conversation

shuding
Copy link
Member

@shuding shuding commented Feb 16, 2024

This PR introduces the ability to accept promises as fallback data for SWR read hooks. The behavior is that the resolved value of the promise will be used as fallback instead of the promise itself.

The resolution of the promise is implemented via use which means that it will suspend the upper boundary.

Copy link

codesandbox-ci bot commented Feb 16, 2024

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

@shuding shuding marked this pull request as ready for review February 16, 2024 14:49
@shuding shuding requested a review from huozhi as a code owner February 16, 2024 14:49
Copy link
Collaborator

@promer94 promer94 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should avoid upgrading react to a specific version here?

we currently have a spearte testing workflow for react@canary at https://github.com/vercel/swr/actions/workflows/test-canary.yml

so i guess we could create a sperate jest config for this and only test it in react canary ?

src/core/use-swr.ts Outdated Show resolved Hide resolved
test/use-swr-promise.test.tsx Outdated Show resolved Hide resolved
@huozhi huozhi merged commit cfcfa9e into main Feb 16, 2024
8 checks passed
@huozhi huozhi deleted the shu/agil branch February 16, 2024 20:53
@huozhi huozhi added this to the v3 milestone Mar 10, 2024
alexandresoro pushed a commit to alexandresoro/ouca that referenced this pull request Dec 23, 2024
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [swr](https://swr.vercel.app) ([source](https://github.com/vercel/swr)) | dependencies | minor | [`2.2.5` -> `2.3.0`](https://renovatebot.com/diffs/npm/swr/2.2.5/2.3.0) |

---

### Release Notes

<details>
<summary>vercel/swr (swr)</summary>

### [`v2.3.0`](https://github.com/vercel/swr/releases/tag/v2.3.0)

[Compare Source](vercel/swr@v2.2.5...v2.3.0)

##### Feature

-   Support promises as fallback data by [@&#8203;shuding](https://github.com/shuding) in vercel/swr#2891
-   Allow to use with React 19 by [@&#8203;vladshcherbin](https://github.com/vladshcherbin) and [@&#8203;devjiwonchoi](https://github.com/devjiwonchoi) in vercel/swr#3047, vercel/swr#2963

##### Patches

-   fix [#&#8203;3030](vercel/swr#3030) and run relateive test in edge-runtime by [@&#8203;promer94](https://github.com/promer94) in vercel/swr#3036
-   fix: Only suspend when using the `fallback` by [@&#8203;shuding](https://github.com/shuding) in vercel/swr#3045
-   fix type check in tests by [@&#8203;huozhi](https://github.com/huozhi) in vercel/swr#3052
-   fix: Replace the deprecated 'window' with 'globalThis' for Deno by [@&#8203;saul-atomrigs](https://github.com/saul-atomrigs) in vercel/swr#2915
-   fix: check if config.fallback is undefined by [@&#8203;taku-hatano](https://github.com/taku-hatano) in vercel/swr#2913
-   fix(infinte): export SWRInfiniteKeyedMutator type by [@&#8203;LeoMcA](https://github.com/LeoMcA) in vercel/swr#2900
-   fix: Improve comparison performance by [@&#8203;shuding](https://github.com/shuding) in vercel/swr#2973
-   Export ScopedMutator type by [@&#8203;joshkel](https://github.com/joshkel) in vercel/swr#2937
-   Improve-Type-Safety-and-State-Access-in-useStateWithDeps-Hook by [@&#8203;O-BERNARDOFOEGBU](https://github.com/O-BERNARDOFOEGBU) in vercel/swr#3027

##### Misc

-   chore: bump dev deps and change example react version to latest by [@&#8203;huozhi](https://github.com/huozhi) in vercel/swr#2894
-   build: fix beta release job by [@&#8203;huozhi](https://github.com/huozhi) in vercel/swr#2895
-   chore: Improve test coverage by [@&#8203;shuding](https://github.com/shuding) in vercel/swr#2903
-   chore: simplify test coverage strategy by [@&#8203;huozhi](https://github.com/huozhi) in vercel/swr#2909
-   build: simplify react-server export and update bundler by [@&#8203;huozhi](https://github.com/huozhi) in vercel/swr#2897
-   examples: add RSC streaming pre-render with promise fallback example by [@&#8203;promer94](https://github.com/promer94) in vercel/swr#2905
-   Drop client-only by [@&#8203;huozhi](https://github.com/huozhi) in vercel/swr#2910
-   Mark package as side-effect free by [@&#8203;htunnicliff](https://github.com/htunnicliff) in vercel/swr#2904
-   Drop exports module field by [@&#8203;huozhi](https://github.com/huozhi) in vercel/swr#2911
-   chore: update pkg script watch by [@&#8203;unliar](https://github.com/unliar) in vercel/swr#2920
-   test: remove console.error times check by [@&#8203;promer94](https://github.com/promer94) in vercel/swr#2918
-   build: bump bundler for perf by [@&#8203;huozhi](https://github.com/huozhi) in vercel/swr#2929
-   Fix bundling of client entry chunks  by [@&#8203;huozhi](https://github.com/huozhi) in vercel/swr#2932
-   ci: fix ci error and upgrade action version by [@&#8203;promer94](https://github.com/promer94) in vercel/swr#2952
-   Add SWRInfiniteMutatorOptions type to export by [@&#8203;ludwigbacklund](https://github.com/ludwigbacklund) in vercel/swr#2954
-   test: update the revalidate function test for useSWRInfinite by [@&#8203;koba04](https://github.com/koba04) in vercel/swr#2955
-   chore: upgrade nextjs dev dep for e2e testing by [@&#8203;huozhi](https://github.com/huozhi) in vercel/swr#3044
-   ci: simplify ci config and bump some deps version by [@&#8203;promer94](https://github.com/promer94) in vercel/swr#2770
-   chore: reorganize entries by [@&#8203;huozhi](https://github.com/huozhi) in vercel/swr#3048
-   Bump bundler and reorganize serialize exports by [@&#8203;huozhi](https://github.com/huozhi) in vercel/swr#3049
-   upgrade use-sync-external-store to support react 19 by [@&#8203;huozhi](https://github.com/huozhi) in vercel/swr#3050

#### New Contributors

-   [@&#8203;htunnicliff](https://github.com/htunnicliff) made their first contribution in vercel/swr#2904
-   [@&#8203;saul-atomrigs](https://github.com/saul-atomrigs) made their first contribution in vercel/swr#2915
-   [@&#8203;unliar](https://github.com/unliar) made their first contribution in vercel/swr#2920
-   [@&#8203;ludwigbacklund](https://github.com/ludwigbacklund) made their first contribution in vercel/swr#2954
-   [@&#8203;taku-hatano](https://github.com/taku-hatano) made their first contribution in vercel/swr#2913
-   [@&#8203;LeoMcA](https://github.com/LeoMcA) made their first contribution in vercel/swr#2900
-   [@&#8203;devjiwonchoi](https://github.com/devjiwonchoi) made their first contribution in vercel/swr#2963
-   [@&#8203;vladshcherbin](https://github.com/vladshcherbin) made their first contribution in vercel/swr#3047
-   [@&#8203;O-BERNARDOFOEGBU](https://github.com/O-BERNARDOFOEGBU) made their first contribution in vercel/swr#3027

**Full Changelog**: vercel/swr@v2.2.5...v2.3.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS44Mi4zIiwidXBkYXRlZEluVmVyIjoiMzkuODIuMyIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Reviewed-on: https://git.tristess.app/alexandresoro/ouca/pulls/413
Reviewed-by: Alexandre Soro <[email protected]>
Co-authored-by: renovate <[email protected]>
Co-committed-by: renovate <[email protected]>
@vpontis
Copy link

vpontis commented Jan 1, 2025

@shuding I think this broke something with our types.

We modify the type of data when creating our hook based on useSWR so that we know data is defined if you specify fallbackData. This is a pretty nice type improvement.

  // We can be confident that data will be nonnull even if the request fails,
  // if we defined fallbackData in the config.
  data: SWRConfig extends { fallbackData: Response }
    ? Response
    : Response | undefined;

This is part of the bigger hook:

import { AxiosError } from "axios";
import { useCallback } from "react";
import useSWR, { KeyedMutator, SWRConfiguration } from "swr";

export type Refresh = () => Promise<unknown>;

type GetApi = any;

export const useZmClient = <
  Path extends keyof GetApi,
  Request extends GetApi[Path]["request"],
  Response extends GetApi[Path]["response"],
  SWRConfig extends SWRConfiguration<Response>,
>({
  path,
  pause,
  args,
  swrConfig,
  additionalKey,
}: {
  path: Path;
  pause?: boolean;
  args?: Request;
  swrConfig?: SWRConfig;
  additionalKey?: string;
}): {
  // We can be confident that data will be nonnull even if the request fails,
  // if we defined fallbackData in the config.
  data: SWRConfig extends { fallbackData: Response }
    ? Response
    : Response | undefined;
  error: AxiosError<{ code?: string }> | undefined;
  mutate: KeyedMutator<Response>;
  refresh: Refresh;
} => {
  const swrKey = [path, JSON.stringify(args)];
  if (additionalKey) {
    swrKey.push(additionalKey);
  }

  const { data, error, mutate } = useSWR(
    pause ? null : swrKey,
    () => null as any,
    swrConfig,
  );
  const refresh = useCallback(async () => {
    await mutate();
  }, [mutate]);

  return { data: data!, error, mutate, refresh };
};

This will now give a type error:

components/hooks/useZmClient.tsx:53:5 - error TS2769: No overload matches this call.
  Overload 1 of 12, '(key: string[] | null, fetcher: ((arg: string[]) => FetcherResponse<Response>) | null, config: SWRConfigurationWithOptionalFallback<SWRConfig> | undefined): SWRResponse<...>', gave the following error.
    Argument of type 'SWRConfig | undefined' is not assignable to parameter of type 'SWRConfigurationWithOptionalFallback<SWRConfig> | undefined'.
      Type 'SWRConfig' is not assignable to type 'SWRConfigurationWithOptionalFallback<SWRConfig> | undefined'.
        Type 'SWRConfiguration<Response>' is not assignable to type 'SWRConfigurationWithOptionalFallback<SWRConfig> | undefined'.
          Type 'SWRConfiguration<Response>' is not assignable to type 'SWRConfigurationWithOptionalFallback<SWRConfig>'.
  Overload 2 of 12, '(key: Key, fetcher: BareFetcher<Response> | null, config: SWRConfigurationWithOptionalFallback<SWRConfig> | undefined): SWRResponse<...>', gave the following error.
    Argument of type 'SWRConfig | undefined' is not assignable to parameter of type 'SWRConfigurationWithOptionalFallback<SWRConfig> | undefined'.
      Type 'SWRConfig' is not assignable to type 'SWRConfigurationWithOptionalFallback<SWRConfig> | undefined'.
        Type 'SWRConfiguration<Response>' is not assignable to type 'SWRConfigurationWithOptionalFallback<SWRConfig> | undefined'.
          Type 'SWRConfiguration<Response>' is not assignable to type 'SWRConfigurationWithOptionalFallback<SWRConfig>'.

53     swrConfig,
       ~~~~~~~~~

I think it would be nice to either:

  1. update SWR types to be smart about the data type based on if fallbackData is an object
  2. update the configuration types a bit to support what I'm trying to do above

Or maybe I'm doing something else wrong. If you'd like me to open an issue or try to fix something, please let me know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants