Next.js Discord

Discord Forum

Does useRouter() from app router return a stable reference?

Unanswered
Japanese Bobtail posted this in #help-forum
Open in Discord
Japanese BobtailOP
I would like to pass a reference to the router as the "extra argument" for Redux Thunk middleware, and so I'm wondering if useRouter() returns a stable reference?

With the pages router, I was able to use the SingletonRouter for this purpose (import Router from 'next/router')

11 Replies

Japanese BobtailOP
Neat, the GPT help bot was able to answer this and link to the pertinent documentation/github issues that give me confidence in the answer :) https://discord.com/channels/752553802359505017/1222256528007106740
Asian black bear
The chatbot "misread" the github issue that it cites
It is only "stable" because a pr wrapped it in useMemo but that is not a semantic guarantee, and using the function outside of the React component tree is def not supported/recommended
Japanese BobtailOP
oh, frick
well do you think it is "stable enough" for passing it along to a redux store that is being built per these instruction: https://redux-toolkit.js.org/usage/nextjs#providing-the-store @Asian black bear ?
e.g.
const StoreProvider = ({ children }) => {
  const storeRef = useRef<AppStore>()
  const router = useRouter()

  if (!storeRef.current) {
    // makeStore is a redux store factory function, and it passes the
    // router along as the `extra` arg for redux thunks and middleware
    storeRef.current = makeStore(router)
  }
}
Asian black bear
@Japanese Bobtail I would consider maybe adding a useEffect to pipe in whatever the current router is and manage its lifecycle.
Japanese BobtailOP
Hmm I’m not sure if redux exposes an API to update that extra arg :thonk:
Unless I create some sort of proxy for the router with useRef
lol
Asian black bear
const StoreProvider = ({ children }) => {
  const storeRef = useRef<AppStore>()
  const router = useRouter()
  
  useEffect(()=>{
    const routerHandle=router;
    storeRef.current.setRouter(routerHandle) //Or whatever redux stuff
    return ()=>{if (storeRef.current.router===routerHandle) storeRef.current.clearStore()}
  },[...])

  if (!storeRef.current) {
    // makeStore is a redux store factory function, and it passes the
    // router along as the `extra` arg for redux thunks and middleware
    storeRef.current = makeStore(router)
  }
}
you would add a reducer for it I think