JSPM

  • Created
  • Published
  • Downloads 156
  • Score
    100M100P100Q79337F
  • License MIT

Utils to define redux reducer/action in typescript

Package Exports

  • redux-ts

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (redux-ts) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

react-ts

Utils to define redux reducer/action in typescript.

build status npm version

npm install --save redux-ts

Store Builder

Create redux store with builder pattern.

import { StoreBuilder, typedToPlainMiddleware, asyncMiddleware } from 'redux-ts'

var store: Redux.Store<StoreState> = 
    new StoreBuilder().withInitialState({test:true})
                      .withMiddleware(typedToPlainMiddleware)
                      .withMiddleware(asyncMiddleware)
                      .withReducersMap(reducers)
                      .build<StoreState>();
} 

Actions

Actions store data that are required on reducers. Declaration of them are succeed with es6 decorators so no need to define type again. Depend on need, action could be either sync or async (like redux-thunk).

import { Action, SyncAction, AsyncAction } from 'redux-ts'
import { push } from 'react-router-redux'


@Action
export class Login extends AsyncAction {
    constructor(public username: string, public password: string) {
        super();
    }
}

@Action
export class Logout extends AsyncAction { }


@Action
export class SetToken extends SyncAction {
    constructor(public token: string) {
        super();
    }
    getTokenKey() {
        return "auth";
    }
}

Reducers

Unlike original redux implementation, reducers can consume both sync and async actions. Each reducer method should return a value even it doesnt change state. Async operations are stored on async actions and will be resolved after original dispatch cycle is finised.

import { ReducerBuilder } from 'redux-ts'
import { Login, Logout, SetToken } from '../actions'
import { push } from 'react-router-redux'


export interface AuthState {
    token?: string;
}

export const authReducer = new ReducerBuilder<AuthState>()
    .init({})

    .handle(Login, (state, action) => {
        
        if (!state.inProgress) {
            action.then(dispatch => {
                fetch(`https://httpbin.org/get?username=${action.username}&password=${action.password}`)
                    .then(x => x.json())
                    .then(data => {
                        dispatch(new SetToken(data.args.username + "|" + data.args.password));
                        dispatch(push("/dashboard"))
                    });
            });
        }

        return null;
    })


    .handle(Logout, (state, action) => {

        action.then(dispatch => {
            dispatch(new SetToken(null));
            dispatch(push("/dashboard"));
        });

        return null;
    })


    .handle(SetToken, (state, action) => {

        if (action.token != null) {
            localStorage.setItem(action.getTokenKey(), action.token);
        }
        else {
            localStorage.removeItem(action.getTokenKey());
        }

        return {
            token: action.token
        };
    })


    .build();

Example

react-material-demo

License

MIT