Redux in TS

Redux in Typescript is different from Redux in JS. We will need define the type specificly. Build Folders as Following.
redux-ts

Create Reducers

we will need define state type and action type here.

import Action from "../actions";
import  {ActionType } from "../action-types";
const initState = 0;

const bankReducer = (state: number = initState, action: Action) => {

    switch (action.type) {
        case ActionType.DEPOSIT:
            return state + action.payload

        case ActionType.WITHDRAW:
            return state - action.payload

        case ActionType.BANKRUPT:
            return 0
            
        default:
            return state
    }
}
export default bankReducer

Also,to avoid typo, we can define action type through enum as following.

export enum ActionType{
    DEPOSIT = 'deposit',
    WITHDRAW = 'withdraw',
    BANKRUPT = 'bankrupt'
}

Then combine all reducers if you have in index file.

import {combineReducers} from 'redux'
import bankReducer from './bankReducer'

const reducers  = combineReducers({
    bank: bankReducer
})

export default reducers

export type State = ReturnType<typeof reducers>

Create Actions

We will need 2 steps. For example, we got 3 types of actions here.

interface DepositAction {
    type: 'deposit',
    payload: number
}
interface WithdrawAction {
    type: 'withdraw',
    payload: number
}
interface BankruptAction {
    type: 'bankrupt',
}

type Action = DepositAction | WithdrawAction | BankruptAction

export default Action

Then create action

import { ActionType } from "../action-types";
import { Dispatch } from "redux";
import Action from "../actions";

export const depositMoney = (amount:number)=>{
    return (dispatch:Dispatch<Action>)=>{
        dispatch({
            type:ActionType.DEPOSIT,
            payload:amount
        })
    }
}

export const withdrawMoney = (amount:number)=>{
    return (dispatch:Dispatch<Action>)=>{
        dispatch({
            type:ActionType.WITHDRAW,
            payload:amount
        })
    }
}

export const bankRupt = ()=>{
    return (dispatch:Dispatch<Action>)=>{
        dispatch({
            type:ActionType.BANKRUPT,
        })
    }
}

Create Store

In store.js, it is same as in JS.

import { createStore,applyMiddleware } from "redux";
import reducers from "./reducers";
import thunk from 'redux-thunk'

export const store = createStore(
    reducers,
    {},
    applyMiddleware(thunk)

)

Export in one file

I would like to export all in one index file. See following

export * as actionCreators from './action-creators'
export * from './store'
export * from './reducers/index'

Use Redux

Redux in TS and React Hooks

import React, { useState,useRef} from 'react';
import { useDispatch, useSelector } from 'react-redux'
import { bindActionCreators } from 'redux';
import { actionCreators, State } from './state';

function App() {
  const dispatch = useDispatch()
  const { depositMoney, withdrawMoney, bankRupt } = bindActionCreators(actionCreators, dispatch)
  const amount = useSelector((state: State) => state.bank)
 

  // handleDeposit
  const handleDeposit = ()=>{
    depositMoney(sliderValue)
  }

  // handle withdraw
    const handleWithdraw = ()=>{
      withdrawMoney(sliderValue)
    }

  return (
    <div className="App">

        {/* current money */}
        <h2 style={{ color: '#a3aab9' }}>TOTAL : {amount}</h2>

        {/* buttons */}
        <div className='btn-wrapper'>
          <button onClick={handleDeposit}>DEPOSIT
          </button>
          <button onClick={handleWithdraw}>WITHDRAW
          </button>
          <button onClick={() => bankRupt()}>BANKRUPT</button>
        </div>
    </div>
  );
}

export default App;