Next.js Discord

Discord Forum

Having issues with useRouter

Answered
sdanialraza posted this in #help-forum
Open in Discord
Avatar
Hey everyone, hope you're all having a good day. I am trying to make it so when the user visits the page, it will get a random id from the custom hook I made and send them to /{random_id}, I've tried this so far but it's giving me hydration errors, not sure what would be the proper way to do this. Quite new to Next.js or React in general so any additional tips would also be very much appreciated:
"use client"

import { useCallback, useEffect } from "react"
import { useRouter } from "next/navigation"

import useRandomItem from "@/hooks/useRandomItem"
import { rawQuotes } from "@/data/rawQuotes"

export default function Page() {
  const router = useRouter()
  const { item: quote, change: changeQuote } = useRandomItem(rawQuotes.filter(quote => quote.verified))

  useEffect(() => {
    router.push(`/${quote?.id}`)
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])
}
Answered by DirtyCajunRice | AppDir
needs to be a function called inside a useEffect
View full answer

15 Replies

Avatar
probably smarter to do this in middleware
if you really wanna do it in client, you need to not do the randomness till after you load, and turn off ssr
Avatar
I don't have any preference, just wanna do what would be the best thing to do here, never done anything with middleware, should I be looking into this?
https://nextjs.org/docs/app/building-your-application/routing/middleware, if so, how would I go about it?
Avatar
check if request path is root, if so redirect to random number. pretty straight forward 🙂
Avatar
Seems like I'd have to do it in client because of the hook, this is my current code, everything works now but it's still showing me hydration errors, what would I do to solve this issue?
"use client"

import { useEffect } from "react"
import { useRouter } from "next/navigation"

import { rawQuotes } from "@/data/rawQuotes"
import useRandomItem from "@/hooks/useRandomItem"

export default function Page() {
  const filteredIds = rawQuotes.filter(quote => quote.verified).map(quote => quote.id)
  const { item: id } = useRandomItem(filteredIds)
  const router = useRouter()

  useEffect(() => router.push(`/${id}`), [id, router])

  return <h1>Loading...</h1>
}
Avatar
if your hook is making random data it wont work
you need the same data both at prerender and at render
Avatar
I'll give you more context about what I am trying to do in hopes to learn what would be a good way to do that, the use random item hook takes an array of items and returns one of the items from that array and a function that can change that item to another one, I wanna make it so when you visit the website, it'll pass in the filteredIds array to the hook and it returns the id so I can use it to redirect the user to a random quote, and then I wanna make it so when they click anywhere inside the div or use specific keys, it'll show another random quote using the change function from use random item hook, what do you think I should do here to achieve this?
Avatar
you need to do that logic after mounted.
so cant be a hook
Avatar
needs to be a function called inside a useEffect
Answer
Avatar
only after window is defined
Avatar
Yeah, I think I understand now, thank you
Avatar
here specifically
@Kawakawa