TypeScript with Redux in a React Application

Integrating TypeScript with Redux in a React application enhances type safety and improves code maintainability. This guide walks through setting up TypeScript with Redux, including defining types and integrating with React components.

Step 1: Install Dependencies

First, install the necessary packages for Redux, React-Redux, and TypeScript types.

npm install redux react-redux @reduxjs/toolkit
npm install @types/react-redux --save-dev

Step 2: Set Up Redux Store

Create the Redux store with TypeScript. Define types for the state and actions, and configure the store.

import { configureStore } from '@reduxjs/toolkit';
import { rootReducer } from './reducers';

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

const store = configureStore({
  reducer: rootReducer,
});

export default store;

Step 3: Define Actions and Reducers

Create action types, action creators, and reducers. Use TypeScript to define the state and action types for strong typing.

import { createSlice, PayloadAction } from '@reduxjs/toolkit';

interface CounterState {
  value: number;
}

const initialState: CounterState = {
  value: 0,
};

const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment: (state) => {
      state.value += 1;
    },
    decrement: (state) => {
      state.value -= 1;
    },
    incrementByAmount: (state, action: PayloadAction<number>) => {
      state.value += action.payload;
    },
  },
});

export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;

Step 4: Connect Redux to React Components

Use the useSelector and useDispatch hooks from React-Redux to connect Redux state and dispatch actions in React components.

import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { RootState, AppDispatch } from './store';
import { increment, decrement, incrementByAmount } from './counterSlice';

const Counter: React.FC = () => {
  const dispatch = useDispatch<AppDispatch>();
  const count = useSelector((state: RootState) => state.counter.value);

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={() => dispatch(increment())}>Increment</button>
      <button onClick={() => dispatch(decrement())}>Decrement</button>
      <button onClick={() => dispatch(incrementByAmount(10))}>Increment by 10</button>
    </div>
  );
};

export default Counter;

Step 5: Integrate Redux Store with React

Wrap the main React component with the Provider component from React-Redux to pass the Redux store to the application.

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

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

Conclusion

Using TypeScript with Redux in a React application provides strong typing and enhances code reliability. By following these steps, the Redux store can be set up with TypeScript, actions and reducers can be defined, and Redux can be integrated with React components.