DEV Community

mhx
mhx

Posted on • Originally published at haecal.my.id

Redux Toolkit with TypeScript

using redux toolkit with typescript

in this case i want to create a simple app. which can add user to redux state

Image description

install redux toolkit

npm i @reduxjs/toolkit react-redux
Enter fullscreen mode Exit fullscreen mode

add typescript for react

npm i typescript @types/react-redux @types/react-dom @types/react @types/node @types/jest
Enter fullscreen mode Exit fullscreen mode

create tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react"
  }
}
Enter fullscreen mode Exit fullscreen mode

lest configure the store by creating new file at src/app/store.ts

import { configureStore } from '@reduxjs/toolkit'
import usersReducer from '../features/users/usersSlice'

export const store = configureStore({
    reducer: {
        // register your reducer here
        users: usersReducer,
    },
})

export type AppDispatch = typeof store.dispatch
export type RootState = ReturnType<typeof store.getState>
Enter fullscreen mode Exit fullscreen mode

cause we are using typescript. its recommended to add custom types hook for dispatch and state selector. so copy and paste this code to app/hooks.ts

import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import type { RootState, AppDispatch } from './store'

// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch = () => useDispatch<AppDispatch>()
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
Enter fullscreen mode Exit fullscreen mode

wrap app component with provider from redux at index.tsx

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import { store } from './app/store'
import { Provider } from 'react-redux'

ReactDOM.render(
    <React.StrictMode>
        <Provider store={store}>
            <App />
        </Provider>
    </React.StrictMode>,
    document.getElementById('root')
)
Enter fullscreen mode Exit fullscreen mode

create src/features/users/usersSlice.ts to store the state, reducer, etc

import { PayloadAction, createSlice } from '@reduxjs/toolkit'
import { RootState } from '../../app/store'

interface UsersState {
    value: [
        {
            id: number
            name: string
        }
    ]
}

const initialState: UsersState = {
    value: [
        {
            id: 1,
            name: 'jack',
        },
    ],
}

export const usersSlice = createSlice({
    name: 'users',
    initialState, // users state
    reducers: {
        // logic to add user
        addUser: (state, action: PayloadAction<{ id: number; name: string }>) => {
            state.value.push(action.payload)
        },
    },
})

// export state selector
export const selectUsers = (state: RootState) => state.users.value
// export dispatch actions
export const { addUser } = usersSlice.actions
// export reducer for register it to the store
export default usersSlice.reducer
Enter fullscreen mode Exit fullscreen mode

lets try using state and reducer action in the app.tsx


import React, { useEffect, useState } from 'react'
import { useAppDispatch, useAppSelector } from './app/hooks'
import { addUser, selectUsers } from './features/users/usersSlice'

export default function App() {
    const dispatch = useAppDispatch()
    const users = useAppSelector(selectUsers)

    const [name, setName] = useState<string>('')

    return (
        <div>
            <p>{JSON.stringify(users)}</p>
            <input
                type="text"
                placeholder="Name"
                onChange={(e) => setName(e.target.value)}
            />
            <button onClick={() => dispatch(addUser({ id: users.length + 1, name }))}>
                Add User
            </button>
        </div>
    )
}
Enter fullscreen mode Exit fullscreen mode

star the server and voila! you finally can use typescript for redux

  • Redux Toolkit ^1.7

  • React Redux ^7.2

  • React ^17

  • TypeScript ^4.5

Top comments (0)