Blog>
Snippets

Setting Up TypeScript with Redux

Showcase how to set up a TypeScript project to work with Redux v5.0.0, demonstrating the necessary configuration and type definitions.
npm install redux @reduxjs/toolkit react-redux
This command installs the necessary Redux packages: redux, @reduxjs/toolkit for Redux logic and middleware, and react-redux for React bindings.
npm install --save-dev @types/react-redux
This command installs the TypeScript definitions for the react-redux bindings as a dev dependency.
interface AppState {
    // Define the state structure here
    counter: number;
}

// actions.ts
export const increment = () => ({
    type: 'INCREMENT'
});

// reducer.ts
import { Action } from 'redux';

const initialState: AppState = {
    counter: 0
};

export function counterReducer(state: AppState = initialState, action: Action): AppState {
    switch (action.type) {
        case 'INCREMENT':
            return { ...state, counter: state.counter + 1 };
        // Add more cases for other actions
        default:
            return state;
    }
}
The code defines the app's state type, actions, and a reducer with TypeScript types. This example includes only one action and a simple counter reducer.
import { configureStore } from '@reduxjs/toolkit';
import { counterReducer } from './reducer';

// store.ts
const store = configureStore({
    reducer: {
        counter: counterReducer
    }
});

export default store;
This code snippet configures the Redux store using Redux Toolkit's configureStore function and includes the previously defined counterReducer.
import React from 'react';
import { Provider } from 'react-redux';
import store from './store';

// index.tsx or App.tsx
const App = () => (
    <Provider store={store}>
        {/* Your app components here */}
    </Provider>
);

export default App;
This sample React component utilizes the react-redux Provider to make the Redux store available to all nested components.
import { useSelector, useDispatch } from 'react-redux';
import { increment } from './actions';

// SomeComponent.tsx
const SomeComponent: React.FC = () => {
    const counter = useSelector((state: AppState) => state.counter);
    const dispatch = useDispatch();

    return (
        <div>
            <p>{counter}</p>
            <button onClick={() => dispatch(increment())}>Increment</button>
        </div>
    );
};

export default SomeComponent;
This React component demonstrates how to use the useSelector hook to access the Redux state and the useDispatch hook to dispatch an action. The state type is used for type safety.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TypeScript with Redux Setup</title>
</head>
<body>
    <div id="root"></div>
    <script src="./bundle.js"></script>
</body>
</html>
Basic HTML template that includes a root div where the React application will mount, and a script tag pointing to a bundled JavaScript file.
* {
    box-sizing: border-box;
}

body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    background-color: #f7f7f7;
    color: #333;
}

#root {
    padding: 20px;
}
Sample CSS that sets a global box-sizing, resets margin, sets a font-family and background for the body, and adds padding to the #root element.