RN: 使用 Mobx

来由

JSFiddler 上面看到 React 结合 Mobx 的一个小例子.

爱不释手, 遂拿来改造一下, 让其能在 RN 上面一展雄风.

之前听过 Mobx, 说是要替代 Redux, 反正我是不知道这些东东, 第一次听说没有什么感觉!
如今又再次偶遇 Mobx, 决定认真学习一下它.

Mobx 简介

Mobx 的 github 地址.
目前关于他和 React Native 的(中文)资料不多, 大多数是关于 React 的.

看来想学好 React Native, 还是要做好 React 的功课呀!

官网给了一个 Mobx 的图:
1

我也是刚接触这个「牛逼闪闪」的 Mobx, 共勉!

效果图

今天的例子很简单, 效果图如下
1

点击 Add
1

点击 Minus
1

下面具体说说如何搞定这个 Demo.

准备「材料」

这里假设你已经具备 React Native 的基本开发环境, 至少成功运行过一次 React Native 的程序.

1.创建 React Native 项目

1
react-native init RNMobxDemo

你也可以给你的工程取一个你喜欢的名字.
这里姑且称之为 RNMobxDemo

2.安装 mobx 和 mobx-react

1
npm i mobx mobx-react --save

3.Counter.js

该文件使用了 mobx 和 mobx-react 的组件.

具体代码:

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
'use strict';
import React, { Component } from 'react';
import {
StyleSheet,
View,
Text,
TouchableHighlight
} from 'react-native';
import { observer } from 'mobx-react/native';
import { observable } from 'mobx';
// 被观察者, 观察 counter 变量
const storer = observable({
counter: 0
});
//---------------------------------
// ES6 写法: Arrow Function
//---------------------------------
storer.plus = () => {
storer.counter ++;
};
storer.minus = () => {
storer.counter --;
};
class Counter extends Component {
render () {
return (
<View style = {styles.container}>
{/*加一*/}
<TouchableHighlight
onPress = {() => {this.props.store.plus()}}>
<Text>Add</Text>
</TouchableHighlight>
{/* 显示处理结果 */}
<Text style = {styles.resultTxtStyle}>
{this.props.store.counter}
</Text>
{/*减一*/}
<TouchableHighlight
onPress = {() => {storer.minus()}}>
<Text>Minus</Text>
</TouchableHighlight>
</View>
);
}
}
// 使用 observer 创建
const CounterComponent = observer(Counter);
export default class ReactionsComponent extends Component {
render () {
return (
<View style = {{flex: 1, marginTop: 64}}>
<CounterComponent store = {storer} />
</View>
);
}
}
/* 样式定义 */
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
justifyContent: 'space-around'
},
resultTxtStyle: {
fontSize: 22,
color: 'red'
}
});

4.index.ios.js

该文件使用自定义的组件 ReactionsComponent

具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import React, { Component } from 'react';
//引入自定义模块
import ReactionsComponent from './js/Mobx/Counter'
import {
AppRegistry
} from 'react-native';
class RNMobxDemo extends Component {
render() {
return(
<ReactionsComponent/>
);
}
}
AppRegistry.registerComponent('RNMobxDemo', () => MZRNTutorial);

Mobx 支持「注解」.

这里的注解就是 ES7 中的 decorators (装饰者模式).

下面代码是使用注解的方式来声明, 但是你需要安装相关的插件(babel plugin)来支持.

安装该插件很简单, 在项目根目录按照下面步骤即可:

Step 1: 创建 .babelrc 文件

1
touch .babelrc

Step 2: 编辑 .babelrc 文件

1
2
3
4
{
'presets': ['react-native'],
'plugins': ['transform-decorators-legacy']
}

Step 3: 安装插件

1
npm i babel-plugin-transform-decorators-legacy babel-preset-react-native-stage-0 --save-dev

修改「Counter.js」, 代码如下:

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
'use strict';
import React, { Component } from 'react';
import {
StyleSheet,
View,
Text,
TouchableHighlight
} from 'react-native';
import { observer } from 'mobx-react/native';
import { observable } from 'mobx';
// 被观察者, 观察 counter 变量
const storer = observable({
counter: 0
});
//---------------------------------
// ES6 写法: Arrow Function
//---------------------------------
storer.plus = () => {
storer.counter ++;
};
storer.minus = () => {
storer.counter --;
};
@observer //使用@方式来前置声明
class Counter extends Component {
render () {
return (
<View style = {styles.container}>
{/*加一*/}
<TouchableHighlight
onPress = {() => {this.props.store.plus()}}>
<Text>Add</Text>
</TouchableHighlight>
{/* 显示处理结果 */}
<Text style = {styles.resultTxtStyle}>
{this.props.store.counter}
</Text>
{/*减一*/}
<TouchableHighlight
onPress = {() => {storer.minus()}}>
<Text>Minus</Text>
</TouchableHighlight>
</View>
);
}
}
export default class ReactionsComponent extends Component {
render () {
return (
<View style = {{flex: 1, marginTop: 64}}>
<Counter store = {storer} />
</View>
);
}
}
/* 样式定义 */
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
justifyContent: 'space-around'
},
resultTxtStyle: {
fontSize: 22,
color: 'red'
}
});

从例子可以看出, storer 相当于 state, 当 state 发生改变了, 视图 View 也跟着变化.
也就是状态驱动.

Android 开发的同学应该知道 Adapter 和 notifyDatasetChanged 的机制, 当数据源发生变化的时候, 可以通知视图进行刷新操作.

这里的 Mobx 也可以这么简单的理解.

Mobx 的强大之处还有很多, 需要慢慢学习和挖掘.

坚持原创技术分享!