I am new to NextJS so the question might sound a trivial so please bear with me. So, basically I want to fetch data from a database and display it in the page at the first render and for that I am trying to use useEffect and useState hooks as follows.
"use client"
import axios from "axios"
import Link from "next/link"
import { useEffect } from "react"
async function ProductsComponent( ) {
const [products,setProducts] = useState<any[]>([])
useEffect(()=>{
async function fetchProducts() {
"use server"
try {
const productsresponse = await axios.get(`${process.env.BASE_URL}/api/productControllers`)
if(productsresponse.status === 200){
setProducts(productsresponse.data.message)
}else{
console.log("Failed to fetch Products")
}
} catch (error) {
}
}
fetchProducts()
},[])
return (
<div className=" flex flex-col">
<h3>Product Name</h3>
{
products?.map(product=>(
<div>
<h4>{product?.productName}</h4>
</div>
</div>
))
}
</div>
)
}
export default ProductsComponent
but I get an error of:
async/await is not yet supported in Client Components, only Server Components.
and if i remove the "use client"
, I get an error of:
You’re importing a component that needs useState. It only works in a Client Component but none of its parents are marked with "use client", so they’re Server Components by default.
So how can I ever fetch data from database and render it in NextJS >=13 ?
I tried defining a separate server side function component that fetches data from database using useEffect and the compoentnt takes the product and setproduct as props and I passed the component in anohter client component where we define states like product ,setProduct but I am still getting an error.
2
Answers
Try removing the
'use server'
from the async function because "use server" functions are not allowed in client components. You can create a ‘use server’ file and You can import them from a "use server" file instead.Updated Code:
Simply removing ‘use server’ worked for me, hoping it will also works for you.
There are two ways to render a page:
Client Side – client gets page & it makes api call & then sets data
in page.
Server side – server gets data & generates page & then sends it to
the client.
Two solutions :
Client side rendering, make a component with
'use client'
at top ofit & import it in your page.
Server side rendering (make page on server & then send to client)
By default Next.js considers a component as Server Component.
Hence it throws a error when u remove
'use client'
from a component which uses (useEffect,useState etc. as this are hydrated/calculated on client side)https://nextjs.org/docs/app/building-your-application/rendering/server-components#using-server-components-in-nextjs
When you use
use client
you make it as client component.https://nextjs.org/docs/app/building-your-application/rendering/client-components#using-client-components-in-nextjs
Read more about Rendering : https://nextjs.org/docs/app/building-your-application/rendering
Here is code with both implementations.
Folder Structure :
locsrcappproductspage.js
Output :
http://localhost:3000/products
—————————————————————————–
Client side rendering:
ProductsList Component
locsrcappcompProductsList.js
Now make a page
locsrcappproducts_clientsidepage.js
& import ProductsListOutput :
http://localhost:3000/products_clientside
"Getting Products ...."
& also in console the data recieved from api