https://github.com/frontainer/reactex
https://github.com/frontainer/reactex
Last synced: about 1 year ago
JSON representation
- Host: GitHub
- URL: https://github.com/frontainer/reactex
- Owner: frontainer
- License: mit
- Created: 2019-09-16T01:26:44.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2023-01-05T05:17:15.000Z (over 3 years ago)
- Last Synced: 2025-03-30T01:02:05.562Z (about 1 year ago)
- Language: TypeScript
- Size: 2.07 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 23
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# reactex
TypeSafe Redux Reducers and Actions Library
Inspired by
[vuex](https://www.npmjs.com/package/vuex),
[typescript-fsa-reducers](https://www.npmjs.com/package/typescript-fsa-reducers),
[typescript-fsa-redux-thunk](https://www.npmjs.com/package/typescript-fsa-redux-thunk)
## dependencies
- [redux](https://www.npmjs.com/package/redux)
- [react-redux](https://www.npmjs.com/package/react-redux)
- [redux-thunk](https://www.npmjs.com/package/redux-thunk)
- [immer](https://www.npmjs.com/package/immer)
## how to use
```
npm i reactex --save
```
please show [example](./example)
## Example
store/store.ts
```
import Reactex from 'reactex'
import { RootModule } from '../modules/Root/RootModule'
import { IRootState } from '../modules/Root/RootState'
export type IAppState = {
root: IRootState
}
const reducers = {
root: RootModule.reducer
}
const rStore = new Reactex.Store(reducers)
export default rStore.store
```
modules/Root/RootModule.ts
```
import { IAppState } from '../../store/store'
import Reactex from 'reactex'
import { IRootState, RootState } from './RootState'
export const RootModule = new Reactex.Module('ROOT', RootState)
export const syncAction = RootModule.sync('INIT', (state, payload) => {
state.syncActionDone = true
return state
})
export const asyncAction = RootModule.async('INIT2', async(payload, dispatch, getState) => {
// async action
return new Promise((resolve) => {
window.setTimeout(() => {
resolve()
}, 3000)
})
}, {
started: (state) => {
state.asyncActionStatus = 'started'
},
failed: (state) => {
state.asyncActionStatus = 'failed'
},
done: (state) => {
state.asyncActionDone = true
state.asyncActionStatus = 'done'
}
})
// Also can write like following
//
// RootModule.case(asyncAction.started, state => {
// state.asyncActionStatus = 'started'
// }).case(asyncAction.failed, (state, { error }) => {
// console.error(error)
// state.asyncActionStatus = 'failed'
// }).case(asyncAction.done, (state, { params, result }) => {
// state.asyncActionDone = true
// state.asyncActionStatus = 'done'
// })
```
modules/Root/RootState.ts
```
export type IRootState = {
syncActionValue: string
syncActionDone: boolean
asyncActionDone: boolean
asyncActionStatus: string
}
export const RootState: IRootState = {
syncActionValue: '',
syncActionDone: false,
asyncActionDone: false,
asyncActionStatus: ''
}
```
then, call action using dispatch function
`dispatch(syncAction('fda'))`
## with react-router
store/store.ts
```
import history from 'store/history'
import Reactex from 'reactex'
import { RootModule } from 'modules/Root/RootModule'
import { IRootState } from 'modules/Root/RootState'
import { connectRouter, routerMiddleware, RouterState } from 'connected-react-router'
export type IAppState = {
root: IRootState,
router: RouterState
}
const rStore = new Reactex.Store({
root: RootModule.reducer,
router: connectRouter(history)
}, [
routerMiddleware(history)
])
export default rStore.store
```
## with redux-devtools
```
const rStore = new Reactex.Store({
root: RootModule.reducer,
router: connectRouter(history)
}, [], true)
```
## useDispatch with AsyncAction
```
const asyncDispatch = useDispatch>()
```
## todo
- docs
- testing