Skip to content

Commit

Permalink
refactor: migrate redux code to be compliant with next.js
Browse files Browse the repository at this point in the history
  • Loading branch information
jy95 committed Dec 1, 2024
1 parent 639b582 commit 42620c2
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 48 deletions.
6 changes: 3 additions & 3 deletions src/app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Providers
import { Providers as ReduxProviders } from "@/redux/provider";
import { ThemeProvider } from "@/providers/ThemeProvider";
import StoreProvider from "@/providers/StoreProvider";

// Next.js Analytics
import { SpeedInsights } from '@vercel/speed-insights/next';
Expand Down Expand Up @@ -57,7 +57,7 @@ export default async function RootLayout(props: Props) {
return (
<html lang={resolvedLocale}>
<body>
<ReduxProviders>
<StoreProvider>
<NextIntlClientProvider locale={resolvedLocale} messages={messages}>
<ThemeProvider lng={resolvedLocale}>
<DashboardAppProvider>
Expand All @@ -80,7 +80,7 @@ export default async function RootLayout(props: Props) {
</DashboardAppProvider>
</ThemeProvider>
</NextIntlClientProvider>
</ReduxProviders>
</StoreProvider>
<SpeedInsights />
<Analytics />
</body>
Expand Down
18 changes: 18 additions & 0 deletions src/providers/StoreProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use client'
import { useRef } from 'react'
import { Provider } from 'react-redux'
import { makeStore, AppStore } from '../redux/Store'

export default function StoreProvider({
children,
}: {
children: React.ReactNode
}) {
const storeRef = useRef<AppStore>(null)
if (!storeRef.current) {
// Create the store instance the first time this renders
storeRef.current = makeStore()
}

return <Provider store={storeRef.current}>{children}</Provider>
}
69 changes: 36 additions & 33 deletions src/redux/Store.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,37 +11,40 @@ import { platformsAPI } from "./services/platformsAPI"
import { genresAPI } from "./services/genresAPI";
import { dlcsAPI } from "./services/dlcsAPI";

/* eslint-disable no-underscore-dangle */
const store = configureStore({
reducer: {
// common reducers
games,
// API calls
[gamesAPI.reducerPath]: gamesAPI.reducer,
[planningAPI.reducerPath]: planningAPI.reducer,
[seriesAPI.reducerPath]: seriesAPI.reducer,
[statsAPI.reducerPath]: statsAPI.reducer,
[testsAPI.reducerPath]: testsAPI.reducer,
[backlogAPI.reducerPath]: backlogAPI.reducer,
[platformsAPI.reducerPath]: platformsAPI.reducer,
[genresAPI.reducerPath]: genresAPI.reducer,
[dlcsAPI.reducerPath]: dlcsAPI.reducer
},
// Adding the api middleware enables caching, invalidation, polling,
// and other useful features of `rtk-query`.
middleware: (getDefaultMiddleware) => getDefaultMiddleware()
.concat(gamesAPI.middleware)
.concat(planningAPI.middleware)
.concat(seriesAPI.middleware)
.concat(statsAPI.middleware)
.concat(testsAPI.middleware)
.concat(backlogAPI.middleware)
.concat(platformsAPI.middleware)
.concat(genresAPI.middleware)
.concat(dlcsAPI.middleware),
})
export default store;
export const makeStore = () => {
return configureStore({
reducer: {
// common reducers
games,
// API calls
[gamesAPI.reducerPath]: gamesAPI.reducer,
[planningAPI.reducerPath]: planningAPI.reducer,
[seriesAPI.reducerPath]: seriesAPI.reducer,
[statsAPI.reducerPath]: statsAPI.reducer,
[testsAPI.reducerPath]: testsAPI.reducer,
[backlogAPI.reducerPath]: backlogAPI.reducer,
[platformsAPI.reducerPath]: platformsAPI.reducer,
[genresAPI.reducerPath]: genresAPI.reducer,
[dlcsAPI.reducerPath]: dlcsAPI.reducer
},
// Adding the api middleware enables caching, invalidation, polling,
// and other useful features of `rtk-query`.
middleware: (getDefaultMiddleware) => getDefaultMiddleware()
.concat(gamesAPI.middleware)
.concat(planningAPI.middleware)
.concat(seriesAPI.middleware)
.concat(statsAPI.middleware)
.concat(testsAPI.middleware)
.concat(backlogAPI.middleware)
.concat(platformsAPI.middleware)
.concat(genresAPI.middleware)
.concat(dlcsAPI.middleware),
});
}

// Infer the type of makeStore
export type AppStore = ReturnType<typeof makeStore>

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch
export type RootState = ReturnType<AppStore['getState']>
export type AppDispatch = AppStore['dispatch']
10 changes: 6 additions & 4 deletions src/redux/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useDispatch, useSelector } from "react-redux";
import type { RootState, AppDispatch } from "./Store";
import { useDispatch, useSelector, useStore } from "react-redux";
import type { RootState, AppDispatch, AppStore } from './Store'

export const useAppDispatch = useDispatch.withTypes<AppDispatch>();
export const useAppSelector = useSelector.withTypes<RootState>();
// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch = useDispatch.withTypes<AppDispatch>()
export const useAppSelector = useSelector.withTypes<RootState>()
export const useAppStore = useStore.withTypes<AppStore>()
8 changes: 0 additions & 8 deletions src/redux/provider.tsx

This file was deleted.

0 comments on commit 42620c2

Please sign in to comment.