Mobx示例

React必备技能之一> 作为优秀的状态管理工作,Redux之外,Mobx也是一个很好的选择哦,用起来非常的简单,花了点时间研究了一下,瞧下面↓

入口文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import React from 'react'
import {render} from 'react-dom'
import Routers from './routers/router'
import { configure } from 'mobx';
import { Provider } from 'mobx-react';
import * as stores from './stores'
configure({ enforceActions: "observed" })

render((
<Provider {...stores}>
<Routers />
</Provider>
), document.getElementById('root'))


// 开启局部热更新
if (module.hot) {
module.hot.accept('./routers/router', () => {
render((
<Provider {...stores}>
<Routers />
</Provider>
), document.getElementById('root'))
})
}

store

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//index.js
import shop from './shop'

export {
shop,
}


//shop.js
import { observable, action, computed, autorun } from 'mobx';
import { create, persist } from 'mobx-persist'

class Shop {
@persist('list') @observable data = [];
@observable action = null;
//持久化测试
@persist('object') @observable persistTestObj = null //对象这里不能写{} 要么就也写成初始值
@persist('list') @observable persistTestArr = []
@persist @observable persistTestNum = 0
@persist @observable persistTestStr = ""

//设置初始化数据
@action
changeInitialData = (data)=>{
this.data = data
}
@computed get totalCount(){
return this.data.reduce(function(prev,next){
return prev + next.count
},0)
}
@computed get totalPrice(){
return this.data.reduce(function(prev,next){
return prev + next.count * next.price
},0)
}
@action
increase = (i)=>{
this.action = 'increase'
this.data.find(function(item,index){
return index == i
}).count += 1
}
@action
setAction = (data)=>{
this.action = data
}
@action
decrease = (i)=>{
this.action = 'decerase'
this.data.find(function(item,index){
return index == i
}).count -= 1
}
}

let _Shop = new Shop()

autorun(()=>{
_Shop.action && console.log(_Shop.action == 'increase' ? '您点击了增加':"您点击了减少")
_Shop.setAction(null)
},{
delay:500 //加上delay 多次快速点击只会出现一次 console
})

const hydrate = create({
storage: localStorage, // or AsyncStorage in react-native.
// default: localStorage
jsonify: true // if you use AsyncStorage, here shoud be true
// default: true
})

hydrate('shop', _Shop,{
persistTestObj:{
"a":10,"b":2
},
persistTestArr:[1,3,20],
persistTestNum:1,
persistTestStr:'2'
}).then(() => console.log('_Shop has been hydrated'))

export default _Shop

container

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import React, {Component} from 'react'
import { inject, observer } from 'mobx-react';
import './index.scss'
import tu1 from 'static/1.jpg'

@inject('shop')
@observer
export default class Home extends Component {
componentDidMount(){
let data = [
{
img:"https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2781512380,2039838908&fm=200&gp=0.jpg",
title:"狗狗",
price:'9.9',
count:1,
},
{
img:"https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2781512380,2039838908&fm=200&gp=0.jpg",
title:"狗狗2",
price:'19.9',
count:0,
},
{
img:"https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2781512380,2039838908&fm=200&gp=0.jpg",
title:"狗狗3",
price:'29.9',
count:10,
}
]
this.props.shop.changeInitialData(data)
}
render () {
const {
data, totalCount, totalPrice,
increase,decrease
} = this.props.shop

return(
<div className="Home">
<img src={tu1} style={{width:100}} alt=""/>
<div className="tu2"></div>
<ul>
{
data.length>0 && data.map((item, i)=>{
return(
<li key={i}>
<img src={item.img} alt=""/>
<span>{item.title}</span>
<em>${item.price}</em>
<div>
<button onClick={()=>decrease(i)}>-</button>
<span>{item.count}</span>
<button onClick={()=>increase(i)}>+</button>
</div>
</li>
)
})
}
</ul>
<p>
<span className="left">数量:{totalCount}个</span>
<span className="right">价格:${totalPrice}</span>
</p>

</div>
)
}
}

温馨提示:

  • autorun这里需要监听的是 new Shop()的对象属性
  • mobx-persist初始值最好在上面定义的地方和下面hydrate的地方都写一下(尤其是对象),否则hydrate不写的话只会在执行其中一个有持久化数据的时候才会保存在本地
  • 善用computedmobx状态改变后不会在组件中通过componentWillReceiveProps拦截到,而是直接进入的render,可以在手机进入的时候通过computed监听需要改变的元素,或者autorun来实现吧
  • 真的可以用autorundelay来实现防抖动哦