Redux Toolkit with TypeScript
Tags: react, redux, typescript, webdev
Published: 2022-02-18 09:23:07

using redux toolkit with typescript


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

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ooag3zyml5uxv418y91f.gif)



install redux toolkit
```sh
npm i @reduxjs/toolkit react-redux
```
 


add typescript for react
```sh
npm i typescript @types/react-redux @types/react-dom @types/react @types/node @types/jest
```
 

 

create **tsconfig.json**
```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"
  }
}
```
 
 

lest configure the store by creating new file at **src/app/store.ts**
```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>
```
 

 

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**
```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
```
 
wrap app component with provider from redux at index.tsx
```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')
)
```

create **src/features/users/usersSlice.ts** to store the state, reducer, etc
```ts
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
```

 

lets try using state and reducer action in the **app.tsx**
```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>
	)
}
```
 

 

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
​