У меня есть проект в Next.js, и я использую действия сервера. Однако я столкнулся с проблемой: я получаю пользовательские данные отдельно на каждой странице, чтобы использовать их на соответствующих страницах. Есть ли способ получить пользовательские данные один раз и использовать их на всех страницах, не загружая их на каждой странице?
Я понимаю, что одним из решений может быть использование контекста или таких инструментов, как **Redux**, для однократной выборки данных и повторного использования сохраненных данных в других частях. Однако я получаю данные в действии сервера в серверном компоненте, что затем потребует от меня использования клиентского компонента.
Есть ли лучший способ справиться с этим? Стоит ли мне рассмотреть возможность получения данных на стороне клиента с помощью управления магазином или есть хорошая альтернатива?
Получение данных в промежуточном программном обеспечении и использование пользовательских заголовков
Вы можете использовать промежуточное программное обеспечение для получения пользовательских данных и присоединения их к заголовкам запросов. Таким образом, к данным можно получить доступ в действиях сервера.
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
import { getUserData } from '@/services/user';
export async function middleware(request: NextRequest) {
const userData = await getUserData();
const response = NextResponse.next();
response.headers.set('x-user-data', JSON.stringify(userData));
return response;
}
export const config = {
matcher: '/:path*',
};
Затем в компонентах вашего сервера вы можете прочитать пользовательские данные из заголовков:
// app/layout.tsx
import React from 'react';
import { headers } from 'next/headers';
export default function RootLayout({ children }) {
const headersList = headers();
const userData = JSON.parse(headersList.get('x-user-data') || '{}');
return (
<html lang = "en">
<body>
<Provider user = {userData}>
{children}
</Provider>
</body>
</html>
);
}
Вот как я решил эту проблему.
export default async function RootLayout({ children }: { children: React.ReactNode }) {
const user = await getCurrentUser() // Hitting tRPC endpoint to get user from DB via sessionId in cookie
return (
<html>
<head></head>
<body>
<TrpcProvider>
<UserProvider defaultUser = {user}>
{children}
</UserProvider>
</TrpcProvider>
</body>
</html>
)
}
/ UserProvider
interface UserProviderProps {
children: React.ReactNode
defaultUser: Public_User_Me_Payload | null | undefined
}
export const UserProvider = ({ children, defaultUser }: UserProviderProps) => {
const result = trpc.public.user.me.useQuery(undefined, {
initialData: defaultUser
})
const value = {
user: result.data || defaultUser,
isLoading: result.isFetching || result.isLoading,
error: result.error,
refetch: result.refetch,
}
return (
<UserContext.Provider value = {value}>
{children}
</UserContext.Provider>
)
}
Нет, этот подход не рекомендуется. Функция промежуточного программного обеспечения выполняется при каждом запросе, поэтому следует избегать получения данных из серверной части или запросов к базе данных. Подробнее об этом можно узнать в этом видео youtube.com/watch?v=N_sUsq_y10U