How to make API calls using React, Redux in TypeScript

Viewed 3754

I'm using typescript-fsa and typescript-fsa-reducers packages to simply create actions and reducers in TypeScript React application.

const actionCreator = actionCreatorFactory();

export function signInHandler(state: UserState, action: Action): UserState {
    // ????

    return { ...state };
}

export const signIn = actionCreator.async<SignInRequest, RequestResponse<SignInResponse>>("USER_SIGNIN");

export const UserReducer = reducerWithInitialState({ signedIn: false } as UserState)
    .casesWithAction([signIn.started, signIn.done], signInHandler)
    .build();

Usage in component:

export default connect<StateProps, DispatchProps>(
  (state: RootState) => ({} as StateProps),
  (dispatch: Dispatch<RootState>) => {
     return {
              signIn: (userName: string, password: string) => dispatch(signIn.started(new SignInRequest(userName, password)))
    };
  }
)(SignIn);

And now I'm stuck. I don't know how to make HTTP calls to my API so I can send request when component dispatches action on dispatch next action when response from API arrives. I would like to use promises. How to solve that?

1 Answers

In React without the typescript-fsa abstraction, you'd make async API callsat the action creator level, since actions are just dispatched POJOs and reducers are supposed to not have any side effects.

There are two projects that make it easy to do this, redux-thunk and redux-saga. I prefer redux-thunk because it is easier to wrap your head around. Basically your action creators get passed the dispatch function, and then they can be responsible for dispatching more than one thing... like so:

function asyncActionCreator(dispatch) {
  dispatch(startAsyncAction());

  doSomethingAsync()
    .then(result => dispatch(completeAsyncAction(result))
    .catch(err => dispatch(errorAsyncAction(err));
}

In your typescript-fsa world, there are some companion packages for both of these: typescript-fsa-redux-thunk and typescript-fsa-redux-saga.

It appears that typescript-fsa-redux-thunk takes a similar approach to the above example, using the concept of an "action worker", which coordinates the dispatching of actions via typescript-fsa. There is a really good example of doing this on the typescript-fsa-redux-thunk repo.

Related