Next.js Discord

Discord Forum

Error when using useState on SSR

Answered
Reddish carpenter ant posted this in #help-forum
Open in Discord
Reddish carpenter antOP
Hi there!

So I'm using drizzle/prisma for my app, and I have queries written to communicate with the database.

It all works great, but I was about to add a a useState, useEffect and I got a 'net' issue, and once I installed that I got this issue..

./node_modules/postgres/src/connection.js:2:0
Module not found: Can't resolve 'tls'

And now the question is, am I using NextJS13 wrong?

How am I supposed to SSR the data, and then use things on client side?

My code isn't anything complicated:
async function PagesIndex() {
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [modalPage, setModalPage] = useState({})

  const pagesList = await getPagesList()
  console.log("hi", pagesList)
  return (

And getPagesList is drizzle ORM query to postgree.
export async function getPagesList(pageCategory  = 1, medium = "desktop", theme = "dark") {
  const query = db
    .select().from(pages)
Answered by Ray
make it client component and import it to the modal
View full answer

195 Replies

American black bear
@Reddish carpenter ant Is the PagesIndex client page or server page?
If it is client page, you can't query data directly inside the client from db.
@American black bear If it is client page, you can't query data directly inside the client from db.
Reddish carpenter antOP
I had to make it client side because of useState, but then that is a bit counter to SSR, isn't it?

I though you can do SSR, and then use client side functions like useState etc?
otherwise, am I meant to create an API route for all of my queries? That seems bit weird
How would you SSR first results, and the other ones client side?
Maybe I'm misunderstanding some concepts here
American black bear
No, you can't do both, for client-side functionality, you need mark component as client component by adding use client at the top.

What you can do is, fetch data in the server component (all components are server components by default). Pass those data to it's child components where, and in those if client side functionality is needed, you can mark those child components as client component.
Reddish carpenter antOP
So just basic API route and it will pre-fetch the first batch on the server? Or all is on client when we use use client, nothing happens on the server at all?
I might be thinking about this the wrong way xd
if you work on dynamic ish webapps, where does SSR comes into play? versus API calls to get data?
Im creating something lke dribbble basically
@Reddish carpenter ant So just basic API route and it will pre-fetch the first batch on the server? Or all is on client when we use `use client`, nothing happens on the server at all?
American black bear
IIRC, Fetching data directly is different from calling API Routes. You call api routes from client component. But in server components, you are already in server, you directly fetch data from DB. Like a node server.
Reddish carpenter antOP
which means a lot of 'use client'
American black bear
Leme share an example, it may help to understand clearly.
Reddish carpenter antOP
Hmmm I think I get the idea with this
but exaple woul dbe appriciated 😄
@American black bear IIRC, Fetching data directly is different from calling API Routes. You call api routes from client component. But in server components, you are already in server, you directly fetch data from DB. Like a node server.
Reddish carpenter antOP
So instead of doing an extra API call, and take an extra step, for the first fetch it fetches things right before sending stuff to the client so its faster right
Reddish carpenter antOP
So need to fetch directly to the server component(to optimize first load), and later use an API to have say a 'load more' button right?
American black bear
For example, Let's take the product page.

-> ProductDetails.tsx (Server component) <- fetch the data, and render content that is not functional like product description, price, text stuff.

Now, if you have a button, which adds the product to the cart, or adds a review. What you need to do is make it a different component.


-> AddToCart.tsx (Client component). You pass the data to this, like product ID.

Now you mark this component as a client component, now you can do useState, useEffect, onClick, etc. In this, you can do client stuff.

Hope you understood, there are other ways to implement this functionality, using server actions, but I suppose it's a different thing.


Hope this helps
@Reddish carpenter ant What if you have a product list, and when you click, it opens a modal, to where you can do things on the modal? and also filter the product list
American black bear
You fetch the product list in the server component. map through the data, and pass the data to the Product component (client). In that client component, you can show a modal.

About Filtering, I might have a video that might help, lemme search it real quick.
use url as state which doesn't require client component 👍🏾
url?modal={0,1}&filters=ids
@Ray use url as state which doesn't require client component 👍🏾 url?modal={0,1}&filters=ids
American black bear
exactly, I have some video which might help.
American black bear
Found it
@Reddish carpenter ant Yeah, that what I had in my mind as well. So need to think about this a little bit different than if it was just react then.
American black bear
Yeah, if you are new to Next 13, you can follow this guy ^, his videos are quite helpful.
@Ray check out https://vercel.com/templates/next.js/nextjs-commerce
American black bear
Perfect demo for this problem 👍
@American black bear https://fxtwitter.com/asidorenko_/status/1680601155460554753
Reddish carpenter antOP
Hmm yeah, so I think what he did in that video makes sense. I need to try this now 😄 Really appriciate the help.

I'll comeback soon, jsut going to test this see if I understood this correctly.

I also never do back-end, just front-end, used nextjs13 before as well but it was mostly api calls and it was fine, but here using drizzle and supabase and giving back-end a shot as well as nextjs13 😄

Btw last question, do you think I should go to nextjs14 right now, or I can do that later? I don't have a lot in my app, but if it would be unecessary work for now
@Ray check out https://vercel.com/templates/next.js/nextjs-commerce
Reddish carpenter antOP
thanks, will check that out as well
im on latest
Reddish carpenter antOP
I like the github link
that seems like a project to learn from
@Reddish carpenter ant that seems like a project to learn from
American black bear
Yes, Next.js has a huge community
Reddish carpenter antOP
I was looking for some projects before but coduln't find any good
but this here seems like its porbbably top quality 😄
American black bear
YOu can checkout this project to find out more about next 13 features: https://github.com/shadcn-ui/taxonomy
Reddish carpenter antOP
I though getStaticProps paths wasn't used in nextjs13 anymore
but Im seeing it used in that ecommerce site
American black bear
I didn't checkout that repo ever, can you share where are they using it?
bit strange how its built
ah wait this doesn't even use the differnt layout folder, its using the old one too right
Reddish carpenter antOP
Thanks, that looks more like it
@Ray use url as state which doesn't require client component 👍🏾 url?modal={0,1}&filters=ids
Reddish carpenter antOP
storing all states like that, modals etc... doesn't seem like a nice solution though is it? Or are you talking about occasional modals here and there?
I understand you store filtering states in the url, but modals etc?
That has tag, search etc state in the URL
but if you click any of those, it will be a modal, without the url state there
it will change the url to a different URL too if you click and open the modal
if you refresh, instead of modal you get the actuall page
the storing modal state in url not sure I like that, unless I'm missing something?
you can also use intercepting routes for modal which like instagram
https://nextjs.org/docs/app/building-your-application/routing/intercepting-routes#modals
@Ray you can also use intercepting routes for modal which like instagram https://nextjs.org/docs/app/building-your-application/routing/intercepting-routes#modals
Reddish carpenter antOP
interesting, that example seems like what Im going for - thanks. It seems like i need to re-learn everyconcept for nextj13 xd
Reddish carpenter antOP
Managed to implement that modal, pretty cool stuff, this is great 😄
@Reddish carpenter ant Managed to implement that modal, pretty cool stuff, this is great 😄
American black bear
Excellent, now if the problem is solved, would you mind marking a message as solution that helped you solve the problem, you can mark your own message too
Reddish carpenter antOP
I still have to implement the API, this here I think was a bit on the side - let me check the data fetching for what we talked before and I'll mark it then if that's fine 😄
unless I should create a new thread?
American black bear
yes, ofcourse, whenever you want 👍
Reddish carpenter antOP
Okay, so I have this in the @modal directory.

The modal works, however... when I try to load in the data
'use client'

import ModalGallery from "@/components/organisms/Modal/ModalGallery";
import { getPageView } from "@/db/queries/page";
import { Dialog, DialogContent } from "@radix-ui/react-dialog";

async function PageModal() {

  const query = await getPageView("eea6af21-010a-46bb-9a2c-83eabe52c707");
  const view = query[0]
  console.log("MODALLLLLLLLLLLLLLLLLL", query[0])

  return (
    <Dialog modal open>
    <DialogContent className="overflow-y-auto max-h-[100%] w-full max-w-full mt-8 rounded-t-2xl mb-8">
      <img src={view.screenshots?.url} />
      hi
    </DialogContent>
    </Dialog>
    )
}

export default PageModal;

It stops working once again, because the getPageView is SSR query to postgresql...

So bit confused here. Am I meant to make an API call here? Because the modal will also have a ton of functionality, such as like, save collection etc...

So kinda going back to what we talked before, but with a modal, you can't really pass down things because they are in the modal right
I did check thegram example, and that's how I did it, but they don't actually use real data but JSON which doesn't really show you you would do real data in the modal
why do you mark it client component?
@Ray why do you mark it client component?
Reddish carpenter antOP
because i get this:
./node_modules\@radix-ui\react-dialog\dist\index.mjs
ReactServerComponentsError:

You're importing a component that needs useEffect. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.
Learn more: https://nextjs.org/docs/getting-started/react-essentials
This is so confusing xd
I get what the error is saying but xd
Answer
something like this
async function PageModal() {

  const query = await getPageView("eea6af21-010a-46bb-9a2c-83eabe52c707");
  const view = query[0]
  console.log("MODALLLLLLLLLLLLLLLLLL", query[0])

  return (
    <ClientModal>
      <img src={view.screenshots?.url} />
      hi
    </ClientModal>
    )
}

export default PageModal;
@Ray make it client component and import it to the modal
Reddish carpenter antOP
So I created a FramePage with 'use client', and imported that to @modal page, and now I get this:
./node_modules/postgres/src/connection.js:5:0
Module not found: Can't resolve 'perf_hooks'
Oh wait you mean client modal
one sec
let me try what you did
import all the radix stuff in a client component
the PageModal remain server component
but with intercepting route, we don't need to use radix-modal
Reddish carpenter antOP
Okay, that seems like it works
cool
Reddish carpenter antOP
So intercepting route does the modal automatically?
hmm, it just render it on top of the page
Reddish carpenter antOP
It seems like I will have to create lots of small client side components, and piece them up in a file wher the data is being fetched ssr right
so this is how dribble/instagram would be done, and then you just attach like or save to the buttons and do the exact same thing
export function Modal({ className, children, ...rest }: ModalProps) {
  return (
    <>
      <div
        className={cn(
          "fixed inset-0 bg-primary/20 backdrop-blur modal-overlay z-50"
        )}
      ></div>
      <div
        className={cn(
          "fixed left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 z-50",
          "bg-white overflow-hidden rounded-lg",
          "animate-in fade-in-0 zoom-in-125 slide-in-from-left-1/2 slide-in-from-top-[48%]",
          className
        )}
        {...rest}
      >
        {children}
      </div>
    </>
  );
}
this is what I use to render the modal in intercepting routes
Reddish carpenter antOP
and to close the modal, do I just change the navigation back? no true/false state? Seems like that's what the docs is saying to use the url as state for open/close?
Close the modal on backwards navigation rather than going to the previous route
Reopen the modal on forwards navigation
So the state of modal is the navigation url
<Link href="/" replace prefetch={false} scroll={false} /> i use this for closing the modal
Reddish carpenter antOP
Interesting
It feels like I'm re-learning everything from scratch xD
yea you should definitely take a look of the doc
keeping less client component mean less javascript send to the user
Reddish carpenter antOP
Yeah, the thing is I'm making something fairly high interactive, and just trying to find a balance with this stuff.

Do you think I'll ever need to create API routes for things like like, bookmark, save to X collection etc? Or when would you consider creating API routes, for what reason?

And side question, if you were building something like webflow, would you use nextjs? I used just vanilla react and build a template builder(pretty much all is client side, drag drop, the engine to find json place, and then change it, ad then render that as html etc... ) but I wonder if there is a sense to port it over to nextj13 - maybe this should go into a different threat xd but umm
@Ray 1, I would use server action instead of api router, maybe trpc + server action. 2, it depends, if you need to work with external api, vite+react might be better
Reddish carpenter antOP
Yeah that's funny you say xd because for one of my client project, which uses extrernal API, because the client would not adehere to conventions, I changed it to nextjs13... but it feels like vite and react might be better.

But is there that big of a difference? Does it really matter? Can you use both without any difficulty? Because there is a small change when I ported client site to nextjs where routing and modals are just slow, need to wait to go to another page, thus creating some flashes but maybe that's just bad routing config not sure xd the client taking few month long break but I really like how nextjs does things xD if I could use it for all projects would be awesome xD
I should prob create a new threat called "How to use nextjs for every project instead of vite react" or something xD
well you can still use next with it, nextjs provide file base routing, server action, caching, image optimization...etc
but if you need to use static export then i would just use vite+react lol
@Ray but if you need to use static export then i would just use vite+react lol
Reddish carpenter antOP
So doesn't hur tto use nextjs for everything? xD Its just I like how nextjs has rigid system of doing things. You can't mess things up. It has to be nextjs way or it won't work. The client I had working on this dashboard, he would chip in, do some dev and get off - that would live things in a mess, not working routing, bad file convention, duplicate files and I'm like... I would have finished this in the next 30minutes, but now I need to fix stuff and that takes me 4hours+ and now I'm a day behind, doing work I don't enjoy that was already working for a very low pay xd

And that for me is probably one of the biggest reason why I feel like when working with othe rpeople that have authority over you or don't follow conventions etc... nextjs can be a life saver - or am I wrong? xD
Reddish carpenter antOP
because if you have a disciplined team that don't step on each other toe, you can make everything work, but sadly that's not the reality for me anyway xd
Reddish carpenter antOP
Ah no, I don't know much about that but don't wanna learn anything new now xD I'm learning back-end now, always did front-end and that was a mistake foro me. back-end is bigg enough xD
lol angular 17 is out and it has ssr too
Reddish carpenter antOP
and a closing self tag too right 😄
Is Angular worth it?
i dont know, haven't tried the new version yet
Reddish carpenter antOP
I wonder, Remix or NextJS? - I've seen that thrown a lot recently. Seems like Remix is taking a lot of devs eyes
too much new there
Reddish carpenter antOP
Yeah xd
i was using remix
Reddish carpenter antOP
too much new stuff xD hard to keep up and I also ahven't done any coding the past month either xd
before nextjs app router
Reddish carpenter antOP
I used to do vite+react routingg exactly like nextjs app router does it
remix is good but I think nextjs is better and i like server copmonent:lolsob:
Reddish carpenter antOP
I extremelly like nextjs way of doing things
well...
at least the stuff you are helping me, I need more time but
overall seems good
build a few project with it and you will be good to go
Reddish carpenter antOP
I think I just need to get more into the nextj13 way of thinking
@Ray build a few project with it and you will be good to go
Reddish carpenter antOP
yeah, building a pet project now, so I will re-do it many times I bet 😄
its really like dribbble/instagram style
so hopefully gonna get enough practice with that doing that there 😄
@Ray ` <Link href="/" replace prefetch={false} scroll={false} />` i use this for closing the modal
Reddish carpenter antOP
Hmmm, when I do that, it changes the URL and page, but the modal stays on the page, open
do you have the default.ts in the intercepting route?
Reddish carpenter antOP
I have this inside @modal/default.tsx
export default function Default() {
  return <div>default modal</div>
}
Or is that meant to be null?
try null
add a catchall route
Reddish carpenter antOP
Same thing
for null*
you have the catch all route?
Reddish carpenter antOP
Hmm
this
Reddish carpenter antOP
Nope
add it
@Ray add it
Reddish carpenter antOP
like this? doesn't seem to work either
do you have the page inside?
Reddish carpenter antOP
I have this
export default function Page() {
  return null
}
inside the page
try restart
Reddish carpenter antOP
same thing : p
This link is correct right
 <Link href="/" replace prefetch={false} scroll={false}>
        Close
      </Link>
yes
hmm
liveshare?
Reddish carpenter antOP
it same
you can try router.back() and see if it work
or you press the back button on the browser
Reddish carpenter antOP
Hmmmm, so when I press the back button on the browser modal disappears, but when I do the link, the modal stays open
yea all you need is the catchall route
Reddish carpenter antOP
Inside the @modal rght
yes
Reddish carpenter antOP
yeah I got that xd
what wrong was it?
Reddish carpenter antOP
it doesn't seem to work
still not work?
Reddish carpenter antOP
nop
what verson of nextjs?
catchall route had some issue with early version
Reddish carpenter antOP
13.5.4
oh no
update to latest man
Reddish carpenter antOP
is 14 not going to mess things up for me right now? xd
well it might lol
depend on what you using
i suggest you init a new project and play with it first
Reddish carpenter antOP
drizzle
radix
how about server action?
Reddish carpenter antOP
I don't think so, but I need to re-do all of that anyway
coz I was using prisma and now swtcihnng to drizzle anyway
ah just update to latest then
Reddish carpenter antOP
yeah
i had issue with catchall route with <14.0.2
Reddish carpenter antOP
The project is on FIREEEEEEEE 🔥 🔥 🔥 🔥

Need some 🚒 🚒 🚒 🚒

I fixed the issue I had in config upgrading to nextj14

And now the Modal works! 😄
It opens and closes, exactly like you said
I'm the slowest developer on this earth right now xD 🐢
but should get up to speed soon hopefully
Really appricaite the help with the modal 😄

Let me do the fetching part and it will be all for this threat, this turned into a bit more than fetching 😄
kinda all related though isn't it
Just need to think about specific way of doing things, in the nextjs way, which is nice, I think this is good for when working with a team 100%
glad you made it
Reddish carpenter antOP
Alright, so I figured out how to get the params and filtering via url

Now I need to ask again, but...

 <select name="pets" id="pet-select">
          <option value="">--Please choose an option--</option>
          {pageCategories.map(item => {
            return <option key={item.id} value={item.id}>{item.name}</option>
          })}
        </select>

Given that pageCategories is coming from database, and considering this needs to change the URL state, would you then create a new component select pass in the pageCategory, and the component should be use client, imported into the server component - and that is nextj14 way of doing things?
the component doesn't need to be client if you use it with form
<form>
<select name="pets" id="pet-select">
      <option value="">--Please choose an option--</option>
      {pageCategories.map(item => {
        return <option key={item.id} value={item.id}>{item.name}</option>
      })}
</select>
</form>


it will navigate to url?pets=value when you hit submit
Reddish carpenter antOP
Alright, I feel like I feel comfortable with this stuff now 😄

Hopefully I can swim in the deep waters now.

I extremelly appriciate your help and dumbboy as well. Very helpful, would probably take me weeks to figure out some of this stuff.

I'll mark the last message as the answer because its hard to pinpoint which message is the one
I should be able to build my little app now 😄 I got a few errors, figured it out, hopefully got the concept in my head now
American black bear
Congrats :success: