Intuitive state management and data flow orchestration
Supports the use of a plain object as the model state It only supports Immutable Record before, now with plain object support, users can choose to use immutability libs such as immer.
Starts to support plugin which intercepts the reducer/action lifecycle and enables people to extend the framework via the plugin. For example, immer supports via plugin: reapex-plugin-immer
app.model
will not be converted to Immutable Record, it will be the same type as the data passed in.
app.model
accepts a plain object or an Immutable Record as initial state and the state
it receives in model.mutations
will be either plain object or Immutable Record based on the type of initial state.For example:
const app = new App()
const model = app.model('counter', { total: 0 })
const [mutations] = model.mutations({
// state here will be a plain object
increase: () => state => ({total: state.total + 1}),
})
With Immutable Record:
const app = new App()
const CounterState = Immutable.Record({{ total: 0 }})
const initialState = new CounterState()
const model = app.model('counter', initialState)
const [mutations] = model.mutations({
// state here will be an Immutable Record
increase: () => state => state.set('total', state.total + 1),
})
Removed actionTypeDelimiter
from App constructor, this will enforce to use /
as action type delimiter
The effects()
trigger map now support throttle
, debounce
and takeLeading
takeLeading
example of only do fetching user once in one timeconst [effects] = model.effects({}, {
requestUser: {
*takeLeading() {
yield call(API.getUser)
}
}
})
debounce
example of decreasing the rate of validation function call when input changesconst [effects] = model.effects({}, {
handleInputChange: {
*debounce(input) {
yield call(validate, input)
},
ms: 500,
}
})
throttle
example of limiting the API calls of requesting suggestions on input changesconst [effects] = model.effects({}, {
requestSuggestions: {
*throttle(input) {
yield call(API.findSuggestions, input)
},
ms: 1000,
}
})
Fixed Typescript strictFunctionTypes
error
minor updates: 1. add immutable to peerDependencies 2. update peerDependency version of react-redux
Removed reducers and sagas from App config which passed into the App constructor when App is initialized.
This causes issues when migrating existing react/redux application to use Reapex. There will be circulation import issue if the existing application has references to Reapex created model
To register existing sagas and reducers, use: app.runSaga() app.setExternalReducers()
Reapex by default creates action type with /
separated strings internally.
For example: 'SomeModelName/MutationName'. When Reapex binding action types to sagas by the calling effect(effectMap)
, it will check if the effectMap
key has a namespace(e.g. SomeModelName
) and it will prefix the key with a namespace when binding sagas if no namespace presents. This expects the key to be separated by /
However, when migrating existing react/redux application to use Reapex, the action types of existing application could be in any pattern, for example, .
or _
separated, or even just a random string.
For Reapex to recognize such action types when binding actions to sagas, now it allows to pass App config like this:
const app = new App({
actionTypeHasNamespace: (actionType: string) => actionType.includes('.')
})