Included templates
next-redux-ts
next-redux-ts
Typescript redux toolkit with skeleton createApi, createSlice and TS redux hooks.
Pasted files structure
├── features
│ └── counterSlice.ts
├── hooks.ts
├── provider.tsx
├── services
│ └── userApi.ts
└── store.ts
├── features
│ └── counterSlice.ts
├── hooks.ts
├── provider.tsx
├── services
│ └── userApi.ts
└── store.ts
Files contents
./features/counterSlice.ts
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
type CounterState = {
value: number;
};
const initialState = {
value: 0,
} as CounterState;
export const counter = createSlice({
name: "counter",
initialState,
reducers: {
reset: () => initialState,
increment: (state) => {
state.value += 1;
},
incrementByAmount: (state, action: PayloadAction<number>) => {
state.value += action.payload;
},
},
});
export const {
increment,
incrementByAmount,
} = counter.actions;
export default counter.reducer;
./features/counterSlice.ts
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
type CounterState = {
value: number;
};
const initialState = {
value: 0,
} as CounterState;
export const counter = createSlice({
name: "counter",
initialState,
reducers: {
reset: () => initialState,
increment: (state) => {
state.value += 1;
},
incrementByAmount: (state, action: PayloadAction<number>) => {
state.value += action.payload;
},
},
});
export const {
increment,
incrementByAmount,
} = counter.actions;
export default counter.reducer;
./hooks.ts
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
import type { RootState, AppDispatch } from "./store";
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
./hooks.ts
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
import type { RootState, AppDispatch } from "./store";
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
./provider.tsx
"use client";
import { store } from "./store";
import { Provider } from "react-redux";
export function Providers({ children }: { children: React.ReactNode }) {
return <Provider store={store}>{children}</Provider>;
}
./provider.tsx
"use client";
import { store } from "./store";
import { Provider } from "react-redux";
export function Providers({ children }: { children: React.ReactNode }) {
return <Provider store={store}>{children}</Provider>;
}
./services/userApi.ts
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
type User = {
id: number;
name: string;
email: number;
};
export const userApi = createApi({
reducerPath: "userApi",
refetchOnFocus: true,
baseQuery: fetchBaseQuery({
baseUrl: "https://your-api-url.com/",
}),
endpoints: (builder) => ({
getUsers: builder.query<User[], null>({
query: () => "users",
}),
getUserById: builder.query<User, { id: string }>({
query: ({ id }) => `users/${id}`,
}),
}),
});
export const { useGetUsersQuery, useGetUserByIdQuery } = userApi;
./services/userApi.ts
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
type User = {
id: number;
name: string;
email: number;
};
export const userApi = createApi({
reducerPath: "userApi",
refetchOnFocus: true,
baseQuery: fetchBaseQuery({
baseUrl: "https://your-api-url.com/",
}),
endpoints: (builder) => ({
getUsers: builder.query<User[], null>({
query: () => "users",
}),
getUserById: builder.query<User, { id: string }>({
query: ({ id }) => `users/${id}`,
}),
}),
});
export const { useGetUsersQuery, useGetUserByIdQuery } = userApi;
./store.ts
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./features/counterSlice";
import { userApi } from "./services/userApi";
import { setupListeners } from "@reduxjs/toolkit/dist/query";
export const store = configureStore({
reducer: {
counterReducer,
[userApi.reducerPath]: userApi.reducer,
},
devTools: process.env.NODE_ENV !== "production",
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({}).concat([userApi.middleware]),
});
setupListeners(store.dispatch);
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
./store.ts
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./features/counterSlice";
import { userApi } from "./services/userApi";
import { setupListeners } from "@reduxjs/toolkit/dist/query";
export const store = configureStore({
reducer: {
counterReducer,
[userApi.reducerPath]: userApi.reducer,
},
devTools: process.env.NODE_ENV !== "production",
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({}).concat([userApi.middleware]),
});
setupListeners(store.dispatch);
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;