Project address: Click on me, welcome star and issue
mp-redux
A state management tool for small programs and lightweight H5 applications, using a simplified version of Redux. It is suitable for lightweight applications mainly because there is no data sharing between components. Therefore, it is not suitable for complex and large front-end applications.
Do you need to use it?
If you’re as confused as I am, try this:
- Code coupling is serious, business code duplication, often change a place will cause many functions to be modified
- The business logic is written in the view logic layer, but there is no way to separate the business code
- The code is getting bloated
- Not touching old code can affect a lot of business logic
Why redux
- Redux is framework-independent, so it’s much more portable, although I’ve done some dirty work on the inside to accommodate multiple platforms
- A single data source makes it easier to track state
- Separating the business logic from the view layer makes the code cleaner and less coupled
- State should be managed in the root container of the page and distributed to child components. To better control the business logic
- The business logic goes into models, which are pure functions, making testing easier
How to use it?
Copy /mp-redux/index.js to your project. Out of the box.
Why not use NPM?
lazy
API usage
- At the system entrance we must initialize the store
const mpState = require('./mp-redux/index.js');
const userInfo = require('./model/userinfo.js');
const logs = require('./model/logs.js');
mpState.createStore({
logs, // These models are redux's Reduce. They must be pure functions and need to return a pure object
userInfo // These models are redux's Reduce. They must be pure functions and need to return a pure object
}, 'onShow') // The second parameter is a hijacked lifecycle function, which is created to address the differences between platforms. Optimization will be considered later
Copy the code
- Create a model
// Model is a data model based on the business
// model/userinfo.js
const actions = require('. /.. /action/logs.js'); // The action mechanism of Redux is also used here
const initState = {
logs: []}module.exports = function (state = initState, action = {}) {
constnewState = { ... state };switch (action.type) {
case actions.addLogs:
const now = new Date(a); newState.logs.push({time: now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds(),
value: action.data
});
return newState;
case actions.clearLogs:
newState.logs = [];
return newState;
default:
returnnewState; }}// action/userinfo.js
module.exports = {
addLogs: 'LOGS_ADD'.clearLogs: 'LOGS_CLEAR'
}
Copy the code
- Use in Page
// Connect is used to inject the subscribed state, and MP-redux automatically injects the Dispatch method into the page object
const mpState = require('. /.. /.. /mp-redux/index.js');
const util = require('.. /.. /utils/util.js');
const logActions = require('. /.. /.. /action/logs.js');
Page(mpState.connect((state) = > {
return {
userInfo: state.userInfo.userInfo,
logs: state.logs.logs
}
},
{ // All business data is stored in the store, so pages with only business data do not need data attributes.
clearLogs() {
this.dispatch({ // Issue actions via the dispatch method to update the data in the store
type: logActions.clearLogs
})
}
}))
Copy the code
- More easily tested business code from above we declare business data in the model, and all business data updates and logic for business data updates are done in the Model (see /model/logs.js). Models are pure functions, so business code is easier to test.
// Don't make fun of ,,,,,, my first time writing test cases. (-_ -)
const actions = require('. /.. /action/logs.js');
const model = require('. /.. /model/logs.js');
test('1. init logs data', () => {
expect(model()).toEqual({
logs: []
})
})
test('2. add new log into empty logs', () = > {const newState = model(undefined, {
type: actions.addLogs,
data: "Test new log"
});
expect({
value: newState.logs[0].value,
len: newState.logs.length
}).toEqual({
value: "Test new log".len: 1
});
})
test('3. add new log into logs', () = > {const newState = model({logs: [{time: '00:00:00'.value: 'the first log'}]}, {
type: actions.addLogs,
data: "the second log"
});
expect({
log1: newState.logs[0].value,
log2: newState.logs[1].value,
len: newState.logs.length
}).toEqual({
log1: "the first log".log2: "the second log".len: 2
});
})
test('4. clear all logs', () = > {const newState = model({ logs: [{time: '00:00:00'.value: 'log1' },
{ time: '00:00:00'.value: 'log2'}]}, {type: actions.clearLogs
});
expect({
len: newState.logs.length
}).toEqual({
len: 0
});
})
Copy the code
Because Internet products are toC businesses, the UI changes almost every day, but the business changes very little. We build the business data model on the front end by modeling the business. And these models are predictable. So it can be tested.
For some Internet products, front-end testing is a very tedious and complex thing. Therefore, this simple solution greatly reduces the risk of front-end code changes, and the additional work is not very large. Regression testing costs for business code can be reduced to some extent.