Я работаю над проектом Next.js, организованным в каталоги, а также реализую Redux для управления состоянием на стороне клиента. У меня есть страницы, расположенные в каталоге приложения t.
Кроме того, я получаю некоторые данные на стороне сервера и хочу инициализировать свое хранилище Redux с помощью этих данных, отображаемых на стороне сервера.
Вот пример того, как я получаю данные в компоненте домашней страницы:
Home.tsx
import { Box, Button, Typography } from "@mui/material";
import blogsecure from "./services/blogSecure";
import { BlogGetData } from "./models/BlogGet";
export const fetchData = async () => {
const response = await blogsecure.get('/blogs/fetch_all'); //<- I want to initalize from this data
if (response.status !== 200) {
throw new Error("Failed to fetch API data");
}
return response.data;
};
const Home = async() => {
const blogs: BlogGetData[] = await fetchData();
return (
<Box sx = {{ position: 'relative', height: '100%' }}>
<Button sx = {{ position: 'absolute', bottom: 16, right: 16 }}>
Create blog
</Button>
{blogs.map((blog) => <Typography>{blog.title}</Typography>)}
</Box>
);
}
export default Home;
Вот как я обрабатываю инициализацию Redux в своих файлах StoreProvider.tsx и store.ts:
StoreProvider.tsx
import { useRef } from 'react';
import { Provider } from 'react-redux';
import { AppStore, makeStore } from '../lib/store';
const StoreProvider = ({ children }: { children: React.ReactNode }) => {
const storeRef = useRef<AppStore>();
if (!storeRef.current) {
storeRef.current = makeStore();
}
return <Provider store = {storeRef.current}>{children}</Provider>;
};
export default StoreProvider;
store.ts
import { configureStore } from '@reduxjs/toolkit';
import authReducer from './feature/auth/authSlice';
import blogsReducer from './feature/blogs/blogFetchSlice';
import userReducer from './feature/user/userSlice';
export const makeStore = () => {
return configureStore({
reducer: {
auth: authReducer,
user: userReducer,
blogs: blogsReducer,
}
});
}
export type AppStore = ReturnType<typeof makeStore>;
export type RootState = ReturnType<AppStore['getState']>;
export type AppDispatch = AppStore['dispatch'];
В моем срезе Redux для загрузки блогов (blogFetchSlice.tsx) я определяю начальное состояние и редукторы следующим образом:
блогFetchSlice.tsx
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import { BlogFetchAllState } from './types'; // Assuming you have defined types for state
export const fetchAllBlogs = createAsyncThunk(
// my async logic here
);
const initialState: BlogFetchAllState = {
blogs: null,<-- If I initialize here it is done from client side
loading: false,
error: null,
current_blog: null
};
const blogFetchSlice = createSlice({
name: 'blogFetchAll',
initialState,
reducers: {
// Additional reducers if needed
},
extraReducers: (builder) => {
// slice actions
}
});
export default blogFetchSlice.reducer;
This setup initializes the Redux store with the server-side rendered data and provides a structure for managing your client-side state with Redux. If you need further assistance or clarification, feel free to ask!
I'm structuring a Next.js project with Redux for client-side state management. Each page resides in the app directory for better organization. I need guidance on initializing the Redux store with data fetched on the server side. Can you help me set up Redux initialization from server-side rendered data in this Next.js project?
В настоящее время это невозможно, поскольку ваше приложение Next.js App Router работает на сервере и в браузере одновременно, поэтому ваш магазин уже создан в браузере до того, как сервер завершит рендеринг.
React потребуется добавить несколько примитивов для ввода данных в поток, прежде чем это станет возможным с помощью Redux.