cant fetch data from client (with server action)
Answered
European anchovy posted this in #help-forum
European anchovyOP
NextJS documentation said, we can use server action to fetch data from client component.
Well in my case, it just says
I don't know what's wrong here, I've checked multiple tutorials, they all say this is how it should be done, but it seems doesn't work at all anymore for me.
I'm trying to implement infinite scroll, and seems this is preventing me from finishing it
Well in my case, it just says
async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding'use client'to a module that was originally written for the server.I don't know what's wrong here, I've checked multiple tutorials, they all say this is how it should be done, but it seems doesn't work at all anymore for me.
I'm trying to implement infinite scroll, and seems this is preventing me from finishing it
// ListingsOfAds.jsx
"use client";
import { useState, useEffect, useRef, useCallback } from "react";
import { AdItem } from "./AdItem";
import { fetchAdsServer } from "./fetchAds";
const ListingsOfAds = () => {
const [ads, setAds] = useState([]);
const [page, setPage] = useState(1);
const [loading, setLoading] = useState(false);
const [hasMore, setHasMore] = useState(true);
const observer = useRef(null);
const fetchAds = async (pageNum) => {
if (loading || !hasMore) return;
setLoading(true);
try {
/* const response = await axios.post("http://xxx.xxx.xxx/ads/list", {
type: "all",
page: page,
limit: 36,
status: "Published",
category: 2,
});
*/
const newAds = await fetchAdsServer(pageNum);
setAds((prevAds) => [...prevAds, ...newAds]);
//don't fetch if there's no more data.
if (newAds.lenght === 0) {
setHasMore(false);
}
} catch (error) {
console.error("Error: ", error);
}
setLoading(false);
};"use server";
const axios = require("axios");
export async function fetchAdsServer(pageNum) {
const response = await axios.post("http://xxx.xxx.xxx/ads/list", {
type: "all",
page: pageNum,
limit: 36,
status: "Published",
category: 2,
});
return response.data.paidAds;
}Answered by B33fb0n3
1. Server actions are not made for data fetching
2. Even if you know the syntax for fetching data in server components, the same syntax does not apply for client components as well.
Solution: use a clientside fetching library if you really need to fetch from the client (examples: SWR, React Query). If you can also fetch the data in your server component, fetch inside your server component and pass the data down to it's component
--- Edit
Removing the
2. Even if you know the syntax for fetching data in server components, the same syntax does not apply for client components as well.
Solution: use a clientside fetching library if you really need to fetch from the client (examples: SWR, React Query). If you can also fetch the data in your server component, fetch inside your server component and pass the data down to it's component
--- Edit
Removing the
async from the AdItem solved the problem18 Replies
@European anchovy NextJS documentation said, we can use server action to fetch data from client component.
Well in my case, it just says `async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding `'use client'` to a module that was originally written for the server.`
I don't know what's wrong here, I've checked multiple tutorials, they all say this is how it should be done, but it seems doesn't work at all anymore for me.
I'm trying to implement infinite scroll, and seems this is preventing me from finishing it
// ListingsOfAds.jsx
"use client";
import { useState, useEffect, useRef, useCallback } from "react";
import { AdItem } from "./AdItem";
import { fetchAdsServer } from "./fetchAds";
const ListingsOfAds = () => {
const [ads, setAds] = useState([]);
const [page, setPage] = useState(1);
const [loading, setLoading] = useState(false);
const [hasMore, setHasMore] = useState(true);
const observer = useRef(null);
const fetchAds = async (pageNum) => {
if (loading || !hasMore) return;
setLoading(true);
try {
/* const response = await axios.post("http://xxx.xxx.xxx/ads/list", {
type: "all",
page: page,
limit: 36,
status: "Published",
category: 2,
});
*/
const newAds = await fetchAdsServer(pageNum);
setAds((prevAds) => [...prevAds, ...newAds]);
//don't fetch if there's no more data.
if (newAds.lenght === 0) {
setHasMore(false);
}
} catch (error) {
console.error("Error: ", error);
}
setLoading(false);
};
"use server";
const axios = require("axios");
export async function fetchAdsServer(pageNum) {
const response = await axios.post("http://xxx.xxx.xxx/ads/list", {
type: "all",
page: pageNum,
limit: 36,
status: "Published",
category: 2,
});
return response.data.paidAds;
}
1. Server actions are not made for data fetching
2. Even if you know the syntax for fetching data in server components, the same syntax does not apply for client components as well.
Solution: use a clientside fetching library if you really need to fetch from the client (examples: SWR, React Query). If you can also fetch the data in your server component, fetch inside your server component and pass the data down to it's component
--- Edit
Removing the
2. Even if you know the syntax for fetching data in server components, the same syntax does not apply for client components as well.
Solution: use a clientside fetching library if you really need to fetch from the client (examples: SWR, React Query). If you can also fetch the data in your server component, fetch inside your server component and pass the data down to it's component
--- Edit
Removing the
async from the AdItem solved the problemAnswer
European anchovyOP
but i need it for infinite scroll. and even SWR library throws me same error. i dont know what's going on. and i've tried some other person demo code, and in their project, even basic fetch works, and i've just run it, and works.
@European anchovy but i need it for infinite scroll. and even SWR library throws me same error. i dont know what's going on. and i've tried some other person demo code, and in their project, even basic fetch works, and i've just run it, and works.
hmm, you can use a route handler with the fetch function to make it work with SWT (idk if we talking about the same lol). Else you can use react query
European anchovyOP
yes SWR. but problem, is that it actually fetches on axios or fetch(), and even on SWR. but when I want to put that into ads (which uses useState), so it can update display. it complains immediatelly with that error. i'm showing list of items (as cards), like:
return (
<>
<div className="grid grid-cols-7 gap-2.5 m-4 mt-0">
{ads.map((item, index) => {
/* attach intersection observer on last element (so we refetch new data, and append that data to list)
return (
<div key={index} ref={index === ads.length - 1 ? lastAdRef : null}>
<AdItem url={item.seo} />
</div>
);
})}
</div>
</>
);when i console.log , axios or fetch data (in useEffect for instance), then it shows output
but moment i want to put that same data in useEffect, it complains
European anchovyOP
here is the whole client component where it should render it
it even fetches
and if i uncomment this : {ads.map((item, index) => (
<div key={index} ref={index === ads.length - 1 ? lastAdRef : null}>
<AdItem url={item.seo} />
</div>
))}
<div key={index} ref={index === ads.length - 1 ? lastAdRef : null}>
<AdItem url={item.seo} />
</div>
))}
then it doesnt complain
and <AdItem is just for displaying data: https://pastebin.com/J08KSncb
i mean, it seems to me, that <AdItem is async. but it's because that component need to get data from different url, to get details
@European anchovy https://pastebin.com/M9WVD2k2
you import your
ListingsOfAds component somewhere. When you remove it from there, does the error persists?@European anchovy solved?
European anchovyOP
yes