DEV Community

Ismail PE
Ismail PE

Posted on

Using RTK with Nextjs

A straight forward example of using Redux Tool Kit with Nextjs app.

redux/hooks.js

import { useDispatch, useSelector, useStore } from "react-redux";
// Use throughout the app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch = useDispatch.withTypes();
export const useAppSelector = useSelector.withTypes();
export const useAppStore = useStore.withTypes();
Enter fullscreen mode Exit fullscreen mode

redux/store.js

import { configureStore } from "@reduxjs/toolkit";
import userReducer from "../features/user/userSlice";

export const makeStore = () => {
  return configureStore({
    reducer: {
      user: userReducer,
      //list more if any
    }
  })
}
Enter fullscreen mode Exit fullscreen mode

redux/StoreProvider.js

'use client'
import { useRef } from 'react'
import { Provider } from 'react-redux'
import { makeStore } from './store'

export default function StoreProvider({ children }) {
  const storeRef = useRef()
  if (!storeRef.current) {
    // Create the store instance the first time this renders
    storeRef.current = makeStore();
  }

  return <Provider store={storeRef.current}>{children}</Provider>
}
Enter fullscreen mode Exit fullscreen mode

features/user/userSlice.js

import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
//import axiosConfig as well

const initialState = {
  userInfo: {},
  isUserLoggedIn: false,
  isUserInfoLoading: true,
  //..add more state variables
};

const reducers = {
  setUserInfoResponse: (state, action) => {
    state.userInfo = action.payload;
    state.isUserLoggedIn = true;
    state.isUserInfoLoading = false;
  },
  //...add more functions to update state
};

export const userSlice = createSlice({
  name: "user",
  initialState,
  reducers,
});

export const getUserInfo = createAsyncThunk(
  "user/getUserInfo",
  async (params, { dispatch }) => {
  const { uid } = params;
    const userInfoResponse = await axiosConfig.get(
      `get_user_info/${uid}`,
    );
    if (userInfoResponse.data.status) {
      dispatch(setUserInfoResponse(userInfoResponse.data.data));
    }
  }
);

export const {
  setUserInfoResponse,
  //list other functions defined above if any
} = userSlice.actions;
export default userSlice.reducer;
Enter fullscreen mode Exit fullscreen mode

_app.js

import StoreProvider from "../redux/StoreProvider";
import { SessionProvider } from "next-auth/react";

function MyApp({ Component, pageProps: { session, ...pageProps } }) {
  return (
   <SessionProvider session={session}>
    <StoreProvider>
     <Component {...pageProps} />
    </StoreProvider>
   </SessionProvider>
  )
}
export default MyApp;
Enter fullscreen mode Exit fullscreen mode

On components:

import { useAppDispatch, useAppSelector } from "../../redux/hooks";
import { getUserInfo } from "../../features/user/userSlice";

...
  const dispatch = useAppDispatch();
  const { isUserLoggedIn, isUserInfoLoading, userInfo } = useAppSelector(state => state.user);

inside useEffect or any logic:
dispatch(getUserInfo({ uid: 123 }));

Enter fullscreen mode Exit fullscreen mode

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

πŸ‘‹ Kindness is contagious

Explore a trove of insights in this engaging article, celebrated within our welcoming DEV Community. Developers from every background are invited to join and enhance our shared wisdom.

A genuine "thank you" can truly uplift someone’s day. Feel free to express your gratitude in the comments below!

On DEV, our collective exchange of knowledge lightens the road ahead and strengthens our community bonds. Found something valuable here? A small thank you to the author can make a big difference.

Okay