The library versions used in this article are as follows:
mobx v6
mobx-react v7
redux v4
react-redux v7
Copy the code
Reducer. Even with middleware such as Redux-Thunk or Redux-saga, there is still too much code in the action layer. Even the naming of actionType needs to be considered. Mobx combined action and Reducer, eliminating the naming of type and the introduction of decorator of ES6 +. The whole code volume and complexity were greatly reduced, and the work efficiency was greatly improved since mobx was used. In addition, mobx stores can be componentalized without the need to maintain an entire store like Redux. However, because redux has so much boilerplate code, it makes the code more normative. Mobx will have more ways to use if there is no reasonable specification, and the maintainability will be poor. It is strongly recommended that MOBx needs a set of specifications/practices
Working principle: Redux: The reducer sends an action. After the reducer receives the corresponding data, it injects it into the components using props, and the components are updated. Mobx: Like Redux, data flows in one direction. Action changes data, proxy listens for data changes, notifies components of updates.
The following is a specific demo to see the use of the two data management libraries:
import React from "react"
import ReactDOM from "react-dom"
import { makeAutoObservable } from "mobx"
import { observer } from "mobx-react"
// Model the application state.
class Timer {
secondsPassed = 0
constructor() {
makeAutoObservable(this)}increase() {
this.secondsPassed += 1
}
reset() {
this.secondsPassed = 0}}const myTimer = new Timer()
// Build a "user interface" that uses the observable state.
const TimerView = observer(({ timer }) = > (
<button onClick={()= > timer.reset()}>Seconds passed: {timer.secondsPassed}</button>
))
ReactDOM.render(<TimerView timer={myTimer} />.document.body)
// Update the 'Seconds passed: X' text every second.
setInterval(() = > {
myTimer.increase()
}, 1000)
Copy the code
// src/flux/Company/action.js
…
export function fetchContacts(){
return dispatch= > {
dispatch({
type: 'FREQUEST_COMPANY_INFO'.payload: {}})}}...// src/flux/Company/reducer.js
const initialState = {};
function reducer (state = initialState, action) {
switch (action.type) {
case 'FREQUEST_COMPANY_INFO': {
return {
...state,
contacts: action.payload.data.data || action.payload.data,
loading: false}}default:
returnstate; }}// src/containers/Company.js
…
class CompanyContainer extends Component {
componentDidMount () {
this.props.loadData({});
}
render () {
return <Company
infos={this.props.infos}
loading={this.props.loading}
/>}}...// function for injecting state into props
const mapStateToProps = (state) = > {
return {
infos: state.companyStore.infos,
loading: state.companyStore.loading
}
}
const mapDispatchToProps = dispatch= > {
return bindActionCreators({
loadData: loadData
}, dispatch);
}
// injecting both state and actions into props
export default connect(mapStateToProps, { loadData })(CompanyContainer);
Copy the code