-
Notifications
You must be signed in to change notification settings - Fork 27k
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
Not able to fetch data from Client Component (infinite fetch() calls) #42180
Comments
Hi @AlexLup06, The problem is with your client component. Async components are only supported on the server. If you remove the You also need to remove the pages folder, that should allow Next to automatically create a I forked your sandbox, you can find all these changes along with a working example here: https://codesandbox.io/s/next-appdir-use-i43p25 |
Hi @apostolos I would not stop calling the |
Hi @AlexLup06, This is an obvious bug in the docs. I left a comment. Per React's RFC, async is only reserved for server components: https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises.md#usepromise |
@AlexLup06 regarding the infinite calling of fetch, based on the RFC again, the promise passed to use() is supposed to be cached (stable identity between renders). There is a I've updated my example (https://codesandbox.io/s/next-appdir-use-i43p25?file=/app/fact.tsx) with how it is supposed work (commented out) plus a simple workaround to avoid infinite fetches with a simple caching of the fetch Promise. It's not correct due to the fact that the cache on the server and the cache on the client are not the same, therefore you get different results from the server render and from the client render. Soon, Next.js will be able to pass the resolved promise from the server to the client somehow. That should avoid double-rendering (the server result will be used). You can read more about this in the RFC: https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises.md#passing-a-promise-from-a-server-component-to-a-client-component |
@apostolos |
Im also having the same infinite fetch call issue. |
The Anyways I tried it and it fixed the infinite fetch issue on client side, but it throws a "Not implemented" error on server. (Remember client components are also rendered on server.) Related issue: #41852 |
Im confused on how there can be such a broken workflow in the docs as an example... |
Yeah, same here to be honest. I know it's beta but considering it's such a fundamental thing and not a detail or edge-case, it is surprising |
I found out how: #41745 (comment) |
I'm having the same issue with infinite fetch in Using cache has an error on the server side
|
Thanks for raising this issue. A few things here. The original problem can be resolved as outlined in #42180 (comment), thanks @apostolos for helping out!
However the infinite fetch should probably not happen, so I will keep this issue open to track it.
I also scanned the docs, and cannot find where we document |
@balazsorban44 here it is https://beta.nextjs.org/docs/data-fetching/fetching#example-fetch-and-use-in-client-components |
"use client";
import { use } from 'react';
async function getData() {
const res = await fetch('https://api.example.com/...');
// The return value is *not* serialized
// You can return Date, Map, Set, etc.
return res.json();
}
export default function Page() {
const name = use(getData());
return '...';
} I cannot see |
@balazsorban44 No, I don't think so. My mistake. There are no |
@balazsorban44 Is there a suggested workaround for the infinite fetch issue? |
The current workaround is described under the above-mentioned link:
|
@balazsorban44 Im doing that currently and still getting the infinite fetching. See the utility function. With code:
|
@balazsorban44 The problem actually exactly happens when calling the function with the fetch in |
The infinite |
The original docs indeed had async client components, that's why many people were confused. I reported it via the inline tool and it was fixed the same day, just a few hours later (that was 5 days ago). |
@palmer-cl every time React calls your render function, the Please this comment for a workaround #42180 (comment) |
@apostolos cache does not take a Promise. See below: |
@palmer-cl See the commented code in my example: https://codesandbox.io/s/next-appdir-use-i43p25?file=/app/fact.tsx Try this: const getData = cache(async () => {
const res = await fetch('https://v2.jokeapi.dev/joke/Any?safe-mode');
return res.json();
}); Then, inside render call the wrapped function: export default function Impact() {
const data = use(getData());
return (<>...</>);
} |
That did it. Thanks @apostolos |
@apostolos Using cache as you suggested gives server errors: Uncaught Error: Not implemented. |
@ShravanSunder are you on |
@apostolos What version of React is required? I am on 18.2.0 |
@AlexLup06 should work fine with anything from 18.2.0 and above or with I made a separate sandbox to test You'll notice that it works correctly. It makes a single fetch on the client and does not go into an infinite loop. However an error shows up with the message "Not implemented.". This is coming from the server and it happens because some parts of caching are still WIP: https://github.com/facebook/react/blob/8e2bde6f2751aa6335f3cef488c05c3ea08e074a/packages/react-server/src/ReactFizzCache.js |
@apostolos |
@apostolos i'm running react@next and next@latest. I do get the not implemented error, does that mean it shouldn't be used currently? |
I had the same issue with the infinity loop, @himyjan provided a link to another workaround in #42265 (comment) |
👋 Hi friends! Really appreciate all the investigation and discussion here. I spoke with the team about this and it looks like, perhaps as expected, we don't have this functionality quite finished yet. We tried to clarify in the docs that fetch is not yet supported in client components - the recommendation right now is to fetch data in server components. This is a feature that will be supported in the future for sure, but this is a beta release and we're not quite there yet. Thank you so much for testing out the new app directory, and I'll update you all here once we do support fetching in client components! |
Using example ”use client";
import { use } from 'react';
import _ from ‘lodash’;
const getData = _.memoize( async () => {
const res = await fetch('https://api.example.com/...');
return res.json();
});
export default function Page() {
const name = use(getData());
return '...';
} |
Hello! I'm still learning about Next13. In my opinion, I found an option how to get rid of the error described in this issue. Take out all the logic of the "use client" client component into a separate component and take it out into a separate file and folder, let's say Components... Everything related to the state and other hooks that you need. After I took it out everything worked as expected. Moreover, the asynchronous function waiting for data makes a request directly to the database on the server side. Here is an example of my code. Notice the "use client" comment. It is this component that is the client component. import s from './personal.module.scss' const {verify} = require('jsonwebtoken') import Calculation_Prog from "../../Components/calculationProg/calculation_prog"; const {UserProjects} = require('../../db/mongo/schemes.js') let getProject = async () => {
} export default async function Personal() {
} function ItemPoroject({item}) {
} |
The infinity fetch happens even without the use(). Any mistake on fetch, e.g. 400 status code === infinity fetches on the client side. When I've added the .catch(() => null) block to the end of fetch, It stopped, before the hot reloader reloaded it... |
This comment was marked as spam.
This comment was marked as spam.
@iSuslov |
As explained by @apostolos, async/await on the client is not yet supported. We have rough plans to support this in the future, and as some of you have discovered, if you use it in a particular way, it can work. But the experience is still very rough so it's not recommended. In the meantime, you should prefer to do as much data fetching as possible in Server Components, and use an established library like SWR for any leftover client cases. I agree that the DX is not great if you accidentally use async/await on the client — we need to fix that in React with better loop detection and warnings if this happens. So I consider this mostly a React issue, not a Next.js one. However we can also do some stuff on the Next.js side to make this less of a footgun, like a lint rule perhaps. I'm going to lock this thread for now but leave the issue open so people know we (the React and Next.js teams) are working on it! |
Actually let's just track this in the React tracker: facebook/react#26801 |
Edit by @acdlite: This is mostly a React issue. We're working to address it: #42180 (comment)
Verify canary release
Provide environment information
What browser are you using? (if relevant)
Version 106.0.5249.119
How are you deploying your application? (if relevant)
next dev
Describe the Bug
I was just playing around getting to know next 13 when I tried fetching data from a Client component.
I literally just copy pasted the example from the docs: https://beta.nextjs.org/docs/data-fetching/fetching#example-fetch-and-asyncawait-in-server-components
The Client Component is used inside
page.tsx
where its wrapped in<Suspense fallback={<div>Loading...</div>}></Suspense>
When running that I get:
Server Component:
Client Component:
Expected Behavior
The root server component in
page.tsx
should render right away and the client component should render when the data was fetched. Before the data is fetched it should sayLoading…
.Link to reproduction
https://codesandbox.io/s/reverent-danilo-zgle45?file=/app/fact.tsx
To Reproduce
Open the link or copy paste the code inside your app
The text was updated successfully, but these errors were encountered: