JSPM

  • Created
  • Published
  • Downloads 156
  • Score
    100M100P100Q79443F
  • 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

redux-ts

Utils to define react redux reducer/action in typescript.

build status dependencies Status devDependencies Status npm version

Now FSA compliant

For breaking changes you can take look CHANGELOG

npm install --save redux-ts

Store Builder

Create redux store with builder pattern.

import { StoreBuilder } from 'redux-ts'

const store = new StoreBuilder<StoreState>()
                        .withInitialState({test:true})
                        .withReducer("reducer", reducer)
                        .withDevTools() // enable chrome devtools
                        .build();
}

Actions

Action declaration can be done with 'createAction' function which takes action type as parameter.

import { createAction } from 'redux-ts'

interface LoginPayload {
  username: string
  password: string
}

interface SetTokenPayload {
  token?: string
}

export const Login = createAction<LoginPayload>('Login')

export const Logout = createAction('Logout')

export const SetToken = createAction<SetTokenPayload>('SetToken')

Reducers

Reducers are consumers for actions to change application state. Difference from original redux implementation is in redux-ts reducers can also dispatch another action asynchronously. Each reducer method should return state value even it doesn't change it. Async dispatch operations will be handled after original dispatch cycle is finished.

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

const tokenKey = 'auth'

export interface AuthState {
  token?: string
}

export const authReducer = new ReducerBuilder<AuthState>()
  .init({
    token: localStorage.getItem(tokenKey) || undefined,
  })

  .handle(Login, (state, action, dispatch) => {
    const { username, password } = action.payload

    fetch(`https://server.com/login?u=${username}&p=${password}`)
      .then(x => x.json())
      .then(data => {
        /*
        * When server respond with token, another action is dispatching.
        */
        dispatch(SetToken(data.token))
        dispatch(push('/dashboard'))
      })

    return state
  })

  .handle(Logout, (state, action, dispatch) => {
    dispatch(SetToken({ token: undefined }))
    dispatch(push('/dashboard'))

    return state
  })

  .handle(SetToken, (state, action) => {
    const token = action.token
    const key = action.getTokenKey()

    if (token) {
      localStorage.setItem(key, token)
    } else {
      localStorage.removeItem(key)
    }

    return {
      ...state,
      token,
    }
  })

Connect

connect method is part of redux library and allows you to connect your react components with redux store. Although you can use your own implementation, this library provides you some syntactic sugar to make it easy.

import * as React from 'react'

import { ChangeTheme } from '../actions/layout.actions'
import { Logout } from '../actions/auth.actions'

import { TopBar } from '../components/topBar'
import { connect } from 'react-redux'
import { mapDispatchToProps, StateToProps } from 'redux-ts'

const mapStoreToProps: StateToProps<StoreState> = map => map

const storeProps = mapStoreToProps(store => ({
  useDarkTheme: !!store.layout.useDarkTheme,
}))

const dispatchProps = mapDispatchToProps({
  Logout,
  ChangeTheme,
})

type MainProps = ReturnType<typeof dispatchProps> &
  ReturnType<typeof storeProps>

const MainContainer: React.SFC<MainProps> = ({ children, ...rest }) => (
  <div>
    <TopBar {...rest} />
    {children}
  </div>
)

export const Main = connect(storeProps, dispatchProps)(MainContainer)

Example

react-material-demo

License

MIT