基于 Redux 的上层封装,数据状态管理库,主要目的是为了简化 Redux 的编写代码。
注意:此库已不维护。 Warning: This library is not maintained.
- There is no need to write
Reducer
, this part will be built automatically when the framework is initialized. - No need to write
action.type
, everything is built in the process of automatic build. - In order to simplify the code, the
Action
method will be changed, and theactions
can be introduced in a global way, which is very convenient. - Developed with the syntax of
ES6
, lightweight, with no additional performance overhead. - Only available for logical split (
combineReducers
) mode. Because logical splitting is used in most projects, it's rare to use only onereducer
. If there is only onereducer
, then there is no need to useRedux
. - Logical splits cannot be nested extensions, they can only be extended vertically in the same level, and a logical split is defined as a
module
. - In order to facilitate the acquisition of
module
, it can be introduced in a global way, andaction
can also be introduced globally. - Provide one-click way to create
store
, write less code. - Ability to get global context at runtime.
- Provide
mixin, helper
to let you easily extend the capabilities ofModule
.
Install directly using npm/yarn, you need to install Redux as well.
npm install redux
npm install redux-fine
There are a few steps to use, and if you have a configuration, you need to put the configuration code first. Then register the Module. After registering the Module, call the store method and return a createStroe
instance to <Provider>
.
import Fine from 'redux-fine';
import IndexModule from './module';
import UserModule from './module/user';
// config
Fine.config({ devtool: true });
// extended function (optional)
Fine.mixin('api', api);
Fine.helper('merge', merge);
// registration module
Fine.module('index', IndexModule);
Fine.module('user', UserModule);
// return to the created store
export default Fine.store();
// Load the store in the Provider
<Provider store={store}>
...
</Provider>
In IndexModule, it is defined as a logically split module.
// module/index.js
import Fine from 'redux-fine';
export default class IndexModule extends Fine.Module {
initState = {
name: 'index-view',
list: [],
}
getList = () => {
// ... Use commit to commit changes to the data.
this.commit(state => ({ ... state }));
// Use this.state to get the data of the current module.
this.state;
// Use this.store to get global store data.
this.store;
// Use this.app to get the global context.
this.app;
// Call the commit of the UserModule in the IndexModule.
this.app.module.user.commit();
// Call the ActionModle's action function in the IndexModule.
this.app.action.user.getList();
// Get the set mixin.
this.app.mixin.api();
// It can also be obtained from an instance.
this.api();
// Get useful methods from the helper.
this.helper.merge();
}
}
Added the ability to bind lifecycles of React components in v4.0.
For the sake of simplicity, make a mapping relationship:
- componentDidCatch -> onDidCatch
- componentWillMount -> onWillMount
- componentDidMount -> onDidMount
- componentWillReceiveProps -> onWillReceiveProps
- componentWillUpdate -> onWillUpdate
- componentDidUpdate -> onDidUpdate
- componentWillUnmount -> onWillUnmount
Use as follows:
- Bind your component.
import Fine, { ComponentBind } from 'redux-fine';
export default connect(
state => ({ state: state.index }),
Fine.action('index'),
)(class IndexView extends ComponentBind('index') {
render() {
// ...
}
}
- Add a lifecycle to the Module.
export default class IndexModule extends Fine.Module {
initState = {
name: 'index-view',
list: [],
}
onDidCatch(err, info) {
console.log('onDidCatch');
}
onWillMount() {
console.log('onWillMount');
}
onDidMount() {
console.log(this.state); // { name: 'index-view', list: [] }
console.log('onDidMount');
}
onWillReceiveProps(nextProps) {
console.log('onWillReceiveProps');
}
onWillUpdate(nextProps, nextState) {
console.log('onWillUpdate');
}
onDidUpdate(prevProps, prevState) {
console.log('onDidUpdate');
}
onWillUnmount() {
console.log('onWillUnmount');
}
}
- this.state, this.store, this.app can't be used in constructors or commit callbacks, they are runtime properties.
- Fine.config, Fine.module are valid until Fine.store() is called, and the setting is invalid after the call.
- action requires an arrow function form, the function starting with an underscore (_xxx) and the non-arrow function form will be filtered.
- The action function returns an empty function, so all return items will be invalid.
class IndexModule extends Fine.Module {
getList1() {
// not action
}
_getList2() {
// not action
}
getList3 = () => {
// is action
return true;
}
}
Fine.module('index', IndexModule);
console.log(Fine.action('index'));
// { getList3: () => {} }
console.log(Fine.action('index').getList3());
// () => {},Invalid return value
You can also directly view the Example code.
The option object includes the following items:
devtool -> bool
- The default is false, true will check and open redux devtool.middlewares -> Array
- redux middleware.
Name is the name of the module. Returns the action function of the specified module.
If there is only one name parameter, try to get the module object. If there are two parameters, register a module.
Returns a store returned by createStroe .
Add a built-in method or property to the Module instance and add it to this at the end. Note that fixed properties with the same name cannot be overwritten.
Add a built-in method or property to the Module instance and add it to this.helper.
This is a base class, you need to inherit it to implement your own module. Module has the following properties and methods.
initState -> any
- the initial data of the module, the default is {}.initialized() -> function
- the lifecycle function, called after the module has been created.store -> any
- a global store shallow reference.state -> any
- the state of this module.app -> object
- global above. - app.module - app.action - app.mixinhelper -> object
- the helper added for the base class. The default is {};commit -> void
- used to commit data changes. Similar to dispatch, but does not require type. There are four ways to commit: -commit(cb: (state) => {});
- Submit a data state change, the callback function returns the most recent state, only changes the state of this module. -commit(cb1: (state) => {}, cb2: (newState) => {});
- The second callback function is triggered after changing the state of the data, the parameter is the new state value. -commit(name: string, cb: (state) => {});
- If the first argument is a string, it is an additional name for the action type. -commit(name: string, cb1: (state) => {}, cb2: (newState) => {});
- The general function of the above.commitAssign(newState)
-