- Notifications
You must be signed in to change notification settings - Fork1
cimdalli/redux-ts
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Utils to define react redux reducer/action in typescript.
For breaking changes you can take lookCHANGELOG
# npmnpm install --save redux-ts# yarnyarn add redux-ts
This is all in one reference implementation ofredux-ts library. You can enhance that solution depend on your needs.
import{StoreBuilder,ReducerBuilder}from'redux-ts'// Define reducer statetypeLayoutState={isDark:boolean}// Define store statetypeStoreState={layout:LayoutState}// Define actionconstswitchTheme=createAction('switchTheme')// Build reducerconstlayoutReducer=newReducerBuilder<LayoutState>().handle(switchTheme,(state,action)=>{constisDark=!state.layout.isDarkreturn{ ...state, isDark}},)// Build storeconststore=newStoreBuilder<StoreState>().withReducerBuildersMap({layout:layoutReducer}).withDevTools()// enable chrome devtools.build()export{mapStoreToProps}=store
importReactfrom'react'import{mapDispatchToProps}from'redux-ts'import{mapStoreToProps,store}from'./store'// Connect storeconstRoot:React.FC=props=>(<Providerstore={store}><Main/></Provider>)// Map store to component propsconststoreProps=mapStoreToProps(store=>({theme:store.layout.isDark ?'dark' :'light',}))// Pass action object to create dispatchable func. (aka. bindActionCreators)constdispatchProps=mapDispatchToProps({ switchTheme})// Connect componentconstMain=connect(storeProps,dispatchProps)(({ theme, switchTheme})=>(<div><span>Current theme:{theme}</span><buttononClick={switchTheme}>Switch theme</button></div>)ReactDOM.render(<Root/>,document.getElementById('app'))
This is sample usage ofconnected-react-router withredux-ts
import{StoreBuilder}from'redux-ts'import{createBrowserHistory}from'history'import{connectRouter,routerMiddleware}from'connected-react-router'exportconsthistory=createBrowserHistory()constrouterReducer=connectRouter(history)exportconststore=newStoreBuilder<StoreState>().withMiddleware(routerMiddleware(history)).withReducer('router',routerReducer).withDevTools()// enable chrome devtools.build()
import{Provider}from'react-redux'import{Route,Switch}from'react-router'import{ConnectedRouter}from'connected-react-router'import{history,store}from'./store'ReactDOM.render(<Providerstore={store}><ConnectedRouterhistory={history}><Switch><Routeexactpath="/"render={()=><div>Match</div>}/><Routerender={()=><div>Miss</div>}/></Switch></ConnectedRouter></Provider>,document.getElementById('react-root'),)
Create redux store with builder pattern.
import{StoreBuilder}from'redux-ts'import{authReducer}from'./reducers/authReducer'conststore=newStoreBuilder<StoreState>().withInitialState({test:true}).withMiddleware().withReducer("auth",authReducer).withDevTools().build();}export{mapStoreToProps}=store
- As generic parameter, it requires store state type in order to match given reducers and the state.
- Any number of middleware, enhancer or reducer can be used to build the state.
mapStoreToPropsis public method that is exposed from store object. This method can be used to map store object to props which are consumed from connected components. Return type isMapStateToPropsParamwhich is compatible withconnect.
Action declaration can be done withcreateAction function which takes action name as parameter and payload type as generic type.Each action should have unique identifier which is first parameter ofcreateAction function. You can also define your metadata type and pass to generic type as second argument.
import{createAction}from'redux-ts'typeLoginPayload={username:string;password:string}typeSetTokenPayload={token?:string}typeTokenMeta={createdAt:Date}exportconstLogin=createAction<LoginPayload>('Login')exportconstLogout=createAction('Logout')exportconstSetToken=createAction<SetTokenPayload,TokenMeta>('SetToken')
- Return value of
createActionfunction isaction creator function that takes payload and metadata objects as parameters. - Return value ofaction creator function is plain js object that havepayload,meta andtype fields which is proposed forFSA.
Reducers are consumer functions that consumes actions and change application state. Difference from original redux implementation inredux-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'connected-react-router'consttokenKey='auth'typeAuthState={token?:string}exportconstauthReducer=newReducerBuilder<AuthState>()// Initial value of sub state.init({token:localStorage.getItem(tokenKey)||undefined,})// Handle SetToken action.handle(SetToken,(state,action)=>{const{ token}=action.payloadif(token){// If token is valid, persist it on local storagelocalStorage.setItem(tokenKey,token)}else{// Otherwise remove from local storagelocalStorage.removeItem(tokenKey)}return{ ...state, token}})// Handle Logout action.handle(Logout,(state,action,dispatch)=>{dispatch(SetToken({token:undefined}))// First clear tokendispatch(push('/dashboard'))// Then navigate to home page, it should redirect to login pagereturnstate// Return state even there is no change})// Handle Login action.handle(Login,(state,action,dispatch)=>{const{ username, password}=action.payload// Request to loginfetch(`https://server.com/login?u=${username}&p=${password}`).then(x=>x.json()).then(data=>{// If valid, store token and navigate to home pagedispatch(SetToken(data.token))dispatch(push('/dashboard'))})returnstate})
connect method is part ofreact-redux library that allows you to connect your react components with redux store.
import*asReactfrom'react'import{connect}from'react-redux'import{mapDispatchToProps}from'redux-ts'import{mapStoreToProps}from'../store'import{ChangeTheme}from'../actions/layout.actions'import{Logout}from'../actions/auth.actions'// Map store object to component propsconststoreProps=mapStoreToProps(store=>({useDarkTheme:!!store.layout.useDarkTheme}))// Map actions to component propsconstdispatchProps=mapDispatchToProps({ Logout, ChangeTheme})exportconstLayout=connect(storeProps,dispatchProps)(({ children,// standard react prop useDarkTheme,// mapped store prop Logout,// mapped action prop ChangeTheme// mapped action prop})=>{constappBarRightElement=(<div><ToggleonToggle={ChangeTheme}label={useDarkTheme:'dark' :'light'}toggled={useDarkTheme}/><FlatButtononClick={Logout}label="logout"/></div>)return(<div><AppBariconElementRight={appBarRightElement}/>{children}</div>)})
react-material-demo (Not up to date)
MIT
About
Utils to define react redux reducers/actions in typescript.
Topics
Resources
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors2
Uh oh!
There was an error while loading.Please reload this page.