question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

With React 18RC, onSuccess does not get called when using Suspense

See original GitHub issue

The below example is running with the package.json referenced at the bottom of this issue.

The code following works as expected which is not using suspense, but using React 18. That is, YES is shown in the rendered output.

import { Suspense, useEffect, useState } from "react";
import useSWR from "swr";

const fetcher = (url) => fetch(url).then((res) => res.json());

function ShowData() {
  const [onSuccessCalled, setOnSuccessCalled] = useState("NO");
  const { data, error } = useSWR(
    "https://jsonplaceholder.typicode.com/todos/2",
    fetcher,
    {
      suspense: false,
      onSuccess(data) {
        console.log("onSuccess called",data);
        setOnSuccessCalled("YES!");
      },
    }
  );
  return (
    <div>
      {JSON.stringify(data)}
      <br />
      onSuccessCalled: {onSuccessCalled}
    </div>
  );
}

function App() {
  return <ShowData />;
}

export default App;

This code, however, has NO remaining showing that onSuccess was never called.

import { Suspense, useEffect, useState } from "react";
import useSWR from "swr";

const fetcher = (url) => fetch(url).then((res) => res.json());

function ShowData() {
  const [onSuccessCalled, setOnSuccessCalled] = useState("NO");
  const { data, error } = useSWR(
    "https://jsonplaceholder.typicode.com/todos/2",
    fetcher,
    {
      suspense: true,
      onSuccess(data) {
        console.log("onSuccess called",data);
        setOnSuccessCalled("YES With Suspense");
      },
    }
  );
  return (
    <div>
      {JSON.stringify(data)}
      <br />
      onSuccessCalled: {onSuccessCalled}
    </div>
  );
}

function App() {
  return (
    <Suspense fallback={<div>Loading....</div>}>
      <ShowData />
    </Suspense>
  );
}

export default App;

package.json follows:

{
  "name": "my-app",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "axios": "^0.24.0",
    "memory-cache": "^0.2.0",
    "next": "12.0.7",
    "react": "^18.0.0-rc.0",
    "react-dom": "^18.0.0-rc.0",
    "swr": "^1.1.1"
  },
  "devDependencies": {
    "@types/node": "16.11.11",
    "@types/react": "17.0.37",
    "eslint": "^7.24.0",
    "eslint-config-next": "^12.0.7",
    "typescript": "4.5.2"
  }
}

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:10 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
promer94commented, Dec 27, 2021

After reviewing the code. It might be hard to change the current behaviour.

In non-suspense mode

  • hook mounted
  • fire request
  • request resolve
  • call onSuccess callback

But in suspense mode

  • hook try to mount
  • beacause there is no data in cache
  • hook throw a promise and suspend
  • onSuccess will not be called (since hook is not mounted)

Beacuse we want to help user to avioid the problems like #286 #787, the config callback will only be called if the hook is mounted.

Could you share your real world use cases with us ?

1reaction
shudingcommented, Dec 30, 2021

Thanks for all the feedback! As you know that currently suspense is still experimental and we’re still exploring the best practices with SWR for the various use cases.

Read more comments on GitHub >

github_iconTop Results From Across the Web

With useSWR onSuccess is never called if within Suspense ...
The code following works as expected which is not using suspense, but using React 18. That is, YES is shown in the rendered...
Read more >
Suspense for Data Fetching (Experimental) - React
It's a mechanism for data fetching libraries to communicate to React that the data a component is reading is not ready yet. React...
Read more >
Experimental React: Using Suspense for data fetching
It simply lets you render a fallback declaratively while a component is waiting for some asynchronous operation (i.e., a network request) to be...
Read more >
React Query: Beyond the Basics - JavaScript in Plain English
We have to use the previously discussed, onSuccess function. ... useQuery and all of the other goodies of react-query, being hooks, can't be...
Read more >
React 18 startTransition, useTransition, and Suspense for data ...
We inspect the minimum viable app for data-fetching with suspense and... ... and useTransition — can be used to make UI more stable....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found