Redux and next/redirect
Answered
Wool sower gall maker posted this in #help-forum
Wool sower gall makerOP
hello can someone explain me why i get a hydration error after i use redirect("/"); also when i use redirect my redux store is not filled.
"use client"
import {useDispatch} from "react-redux";
import {AppDispatch, useAppSelector} from "@/lib/redux/store";
import {logIn} from "@/lib/redux/features/auth/auth-slice";
import {AuthResponse} from "@/app/actions/authAction";
import {redirect} from "next/navigation"
export const AuthProvider = ({auth}: { auth: AuthResponse }) => {
const dispatch = useDispatch<AppDispatch>();
if (auth.isAuth) {
dispatch(logIn({username: auth.user.userName, discordId: auth.user.discordId}));
//redirect("/");
}
const username = useAppSelector((state) => state.authReducer.value.username);
return (
<div>
{auth.isAuth ? <div>logged in as {username}</div> : <div>not logged in {redirect("/login")}</div>}
</div>
);
};Answered by Ray
"use client"
import {useDispatch} from "react-redux";
import {AppDispatch, useAppSelector} from "@/lib/redux/store";
import {logIn} from "@/lib/redux/features/auth/auth-slice";
import {AuthResponse} from "@/app/actions/authAction";
export const AuthProvider = ({auth}: { auth: AuthResponse }) => {
const dispatch = useDispatch<AppDispatch>();
const username = useAppSelector((state) => state.authReducer.value.username);
const router = useRouter()
useEffect(() => {
if (auth.isAuth) {
dispatch(logIn({username: auth.user.userName, discordId: auth.user.discordId}));
router.push("/");
}
}, [auth.isAuth])
if (!auth.isAuth) return <div>not logged in</div>
return <div>logged in as {username}</div>;
};you should redirect inside
useEffect()20 Replies
English Angora
redirect function is for server components, server actions and route handlers try it with useRouter this hook is for redirecting in client side
your component is client component
@English Angora redirect function is for server components, server actions and route handlers try it with useRouter this hook is for redirecting in client side
Wool sower gall makerOP
Warning: Cannot update a component (`Router`) while rendering a different component (`AuthProvider`). To locate the bad setState() call inside `AuthProvider`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render
at AuthProvider (webpack-internal:///(app-pages-browser)/./src/components/auth-provider.tsx:15:11)
at div
at InnerLayoutRouter (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:242:11)
at RedirectErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/redirect-boundary.js:73:9)
at RedirectBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/redirect-boundary.js:81:11)
at NotFoundBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/not-found-boundary.js:84:11)
at LoadingBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:335:11)
at ErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/error-boundary.js:161:11)
at InnerScrollAndFocusHandler (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:152:9)
at ScrollAndFocusHandler (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:227:11)
at RenderFromTemplateContext (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/render-from-template-context.js:16:44)points to the router.push
and when i press F5 i get the hydration error...
Error: Hydration failed because the initial UI does not match what was rendered on the server.
Warning: Expected server HTML to contain a matching <a> in <div>.
Warning: Expected server HTML to contain a matching <a> in <div>.
"use client"
import ProfileButton from "@/components/profile-button";
import {AppDispatch, useAppSelector} from "@/lib/redux/store";
import {cn} from "@/lib/utils";
import {buttonVariants} from "@/components/ui/button";
import Link from "next/link";
import {useDispatch} from "react-redux";
import {useEffect, useState} from "react";
export default function NavLogin() {
const authState = useAppSelector((state) => state.authReducer.value);
console.log(authState.isAuth);
return (
<div>
{authState.isAuth ?
<ProfileButton/>
:
<div>
<Link href="/login" className={cn(buttonVariants({variant: "ghost"}))}>Login</Link>
</div>}
</div>
)
}English Angora
import NavLogin dynamically in parent component with ssr false
const ComponentC = dynamic(() => import('../components/C'), { ssr: false })
like this
Wool sower gall makerOP
import {MobileNav} from "@/components/mobile-nav";
import {getAuth} from "@/app/actions/authAction";
import {ModeToggle} from "@/components/theme-toggle";
import {Separator} from "@/components/separator";
import dynamic from "next/dynamic";
const NavLogin = dynamic(() => import("./nav-login"))
export default async function SiteHeader({shouldShow}: { shouldShow: boolean }) {
const auth = await getAuth();
console.log("SiteHeader auth:", auth);
return (
<header
className="sticky top-0 z-50 w-full border-b border-border/40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
<div className="container flex h-14 max-w-screen-2xl items-center">
<MainNav items={siteConfig.mainNav} auth={auth.isAuth}/>
<MobileNav items={siteConfig.mainNav} auth={auth.isAuth}/>
<div className="flex flex-1 items-center justify-between space-x-2 md:justify-end">
<div className="w-full flex-1 md:w-auto md:flex-none">
{/*<Button className={cn(*/}
{/* "relative h-8 w-full justify-center rounded-[0.5rem] bg-background text-lg font-sans text-muted-foreground md:w-40 lg:w-64"*/}
{/*)}><span className="hidden lg:inline-flex ">Login</span><span className="flex lg:hidden">Login...</span></Button>*/}
</div>
<nav className="flex h-8 items-center">
<ModeToggle/>
<Separator orientation="vertical" className="mr-3"/>
<NavLogin></NavLogin>
</nav>
</div>
</div>
</header>
)
} like this?still same error
English Angora
const ComponentC = dynamic(() => import('../components/C'), { ssr: false })
you are not doing ssr false
Wool sower gall makerOP
yea i did now still same error
still pointing to the router.push in my AuthProvider
root layout.tsx
export default function RootLayout({children}: RootLayoutProps) {
return (
<>
<html lang="en" suppressHydrationWarning>
<body
className={cn(
"min-h-screen bg-background font-sans antialiased ",
fontSans.className
)}
>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
<ReduxProvider>
<div className="relative flex min-h-screen flex-col bg-background">
<SiteHeader/>
<main className="flex-1">{children}</main>
</div>
<TailwindIndicator/>
</ReduxProvider>
</ThemeProvider>
</body>
</html>
</>
)
}@Wool sower gall maker hello can someone explain me why i get a hydration error after i use redirect("/"); also when i use redirect my redux store is not filled.
ts
"use client"
import {useDispatch} from "react-redux";
import {AppDispatch, useAppSelector} from "@/lib/redux/store";
import {logIn} from "@/lib/redux/features/auth/auth-slice";
import {AuthResponse} from "@/app/actions/authAction";
import {redirect} from "next/navigation"
export const AuthProvider = ({auth}: { auth: AuthResponse }) => {
const dispatch = useDispatch<AppDispatch>();
if (auth.isAuth) {
dispatch(logIn({username: auth.user.userName, discordId: auth.user.discordId}));
//redirect("/");
}
const username = useAppSelector((state) => state.authReducer.value.username);
return (
<div>
{auth.isAuth ? <div>logged in as {username}</div> : <div>not logged in {redirect("/login")}</div>}
</div>
);
};
"use client"
import {useDispatch} from "react-redux";
import {AppDispatch, useAppSelector} from "@/lib/redux/store";
import {logIn} from "@/lib/redux/features/auth/auth-slice";
import {AuthResponse} from "@/app/actions/authAction";
export const AuthProvider = ({auth}: { auth: AuthResponse }) => {
const dispatch = useDispatch<AppDispatch>();
const username = useAppSelector((state) => state.authReducer.value.username);
const router = useRouter()
useEffect(() => {
if (auth.isAuth) {
dispatch(logIn({username: auth.user.userName, discordId: auth.user.discordId}));
router.push("/");
}
}, [auth.isAuth])
if (!auth.isAuth) return <div>not logged in</div>
return <div>logged in as {username}</div>;
};you should redirect inside
useEffect()Answer
Wool sower gall makerOP
Ray you are a god did you know that and also thx to coding-lover â¤ï¸
English Angora
Welcome