feat: 前端添加user状态管理
This commit is contained in:
25
apps/frontend/app/ClientProvider.tsx
Normal file
25
apps/frontend/app/ClientProvider.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect } from 'react';
|
||||
import { useUserStore } from '@/store/useUserStore';
|
||||
import { User } from '@/lib/types/user';
|
||||
|
||||
export function ClientProvider({
|
||||
initialUser,
|
||||
children,
|
||||
}: {
|
||||
initialUser: User | null;
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const setUser = useUserStore((state) => state.setUser);
|
||||
const setInitialized = useUserStore((state) => state.setInitialized);
|
||||
|
||||
useEffect(() => {
|
||||
if (initialUser) {
|
||||
setUser(initialUser);
|
||||
}
|
||||
setInitialized();
|
||||
}, [initialUser, setUser, setInitialized]);
|
||||
|
||||
return <>{children}</>;
|
||||
}
|
||||
@@ -3,6 +3,8 @@ import "./globals.css";
|
||||
import { ThemeProvider } from "../components/theme-provider";
|
||||
import { metadata } from "./config/metadata";
|
||||
import { Toaster } from "sonner";
|
||||
import { UserAPI } from "@/lib/api/server";
|
||||
import { ClientProvider } from "./ClientProvider";
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
@@ -16,17 +18,20 @@ const geistMono = Geist_Mono({
|
||||
|
||||
export { metadata };
|
||||
|
||||
export default function RootLayout({
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
const user = await UserAPI.me().catch(() => null);
|
||||
|
||||
return (
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<body
|
||||
className={`${geistSans.variable} ${geistMono.variable} antialiased min-h-screen flex flex-col`}
|
||||
suppressHydrationWarning
|
||||
>
|
||||
<ClientProvider initialUser={user}>
|
||||
<ThemeProvider
|
||||
attribute="class"
|
||||
defaultTheme="system"
|
||||
@@ -38,6 +43,7 @@ export default function RootLayout({
|
||||
<Toaster />
|
||||
</main>
|
||||
</ThemeProvider>
|
||||
</ClientProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
27
apps/frontend/store/useUserStore.ts
Normal file
27
apps/frontend/store/useUserStore.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
// store/useUserStore.ts
|
||||
import { User } from '@/lib/types/user';
|
||||
import { create } from 'zustand';
|
||||
import { devtools } from 'zustand/middleware';
|
||||
|
||||
interface UserState {
|
||||
user: User | null;
|
||||
isLoading: boolean;
|
||||
initialized: boolean;
|
||||
|
||||
// Actions
|
||||
setInitialized: () => void;
|
||||
setUser: (user: User | null) => void;
|
||||
clearUser: () => void;
|
||||
}
|
||||
|
||||
export const useUserStore = create<UserState>()(
|
||||
devtools((set, get) => ({
|
||||
user: null,
|
||||
isLoading: false,
|
||||
initialized: false,
|
||||
|
||||
setInitialized: () => set({ initialized: true }),
|
||||
setUser: (user) => set({ user, isLoading: false }),
|
||||
clearUser: () => set({ user: null }),
|
||||
}))
|
||||
);
|
||||
Reference in New Issue
Block a user