Search code examples
typescriptreduxreact-reduxredux-thunkreact-tsx

React-Redux Reducer Doesn't Get Called


I have set up my state, actions, reducers, types (using TypeScript), and a few calls to these actions. The action calls the appropriate function (I'm not sure they truly return the data), but the reducer for this state slice does not every get called.

I have read through the React-Redux documentation, looked through Stack Overflow questions, and asked a coworker. Nothing I have found has helped.

Page.tsx

render() {
  this.props.getCards();
  ...
}

const mapStateToProps = (state: ApplicationState) => ({ ...state.cards, ...state.requests });

const actions = {
  ...CardActions.actionCreators,
  ...RequestActions.actionCreators,
};

export default connect(
  mapStateToProps,
  actions,
)(ApprovalPage);

/store/cards/types.ts

export interface ICard {
  id: string;
  cardNumber: number;
  owner: string;
}

export interface ICardState {
  cards: ICard[];
}

export const GET_CARDS = 'GET_CARDS';

interface IGetCardsAction {
  type: typeof GET_CARDS;
  payload: ICardState;
}

export type CardActionTypes = IGetCardsAction;

/store/cards/actions.ts

import { addTask } from 'domain-task';
import { AppThunkAction } from '..';
import * as api from '../../api/cardsAPI';
import {
  CardActionTypes,
  GET_CARDS,
  ICard,
} from './types';

export const actionCreators = {
  getCards: (): AppThunkAction<CardActionTypes> => (dispatch) =>  {
    const fetchTask = api.getCardsApi(location).then((data: ICard[]) => {
      console.log(data);
      dispatch ({
        payload: { cards: data },
        type: GET_CARDS,
      });
    });
    addTask(fetchTask);
  },
};

/api/cardsApi.ts

import axios from 'axios';
import { ICard } from '../store/cards/types';

export function getCardsApi(location: string): any{
  return axios
    .get(url, {
      params: {
        location,
      },
    })
    // Mock data
    .then((response) => {
      const card: ICard = {
        cardNumber: 12345,
        id: '1235464789',
        owner: '123123',
      };
      const cards: ICard[] = [ card ];
      return cards;
    })
    .catch((error) => {
      console.log(error);
    });
}

/store/cards/reducers.ts

import { Reducer } from 'redux';
import {
  CardActionTypes,
  GET_CARDS,
  ICardState,
} from './types';

const initialState: ICardState = {
  cards: [],
};

export const reducer: Reducer<ICardState> = (
  state: ICardState = initialState,
  action: CardActionTypes,
): ICardState => {
  console.log(action)
  switch (action.type) {
    case GET_CARDS:
      return {
        ...state,
        cards: action.payload.cards,
      };
    default:
      return state;
  }
};

/store/index.ts

import * as CardReducers from '../store/cards/reducers';
import * as CardTypes from '../store/cards/types';

export interface ApplicationState {
  cards: CardTypes.ICardState;
}

export const reducers = {
  cards: CardReducers.reducer,
};

export interface AppThunkAction<TAction> {
  (dispatch: (action: TAction) => void, getState: () => ApplicationState): void;
}

Expected result: state is updated to include the cards pulled from the API.

Edit: I just discovered that my actions and types are loaded into the page source, but the reducers aren't. Any ideas about what could be causing this?


Solution

  • For those curious...

    I had several files become permanently transpiled into JS, meaning that they did not update when I edited the corresponding TS files. One such file included where I registered my reducers. Deleting those files fixed my issues.