RN-mobX 简单使用
2018-08-30 本文已影响412人
精神病患者link常
本文问题解决
1.单个页面的数据存放、修改、即时更新
2.全局数据的存放、修改、即时更新
❗️思考题:
1.每个页面都有一个确定的store,里面进行属性声明、方法声明,将网络请求及所有处理数据的方法都写在store里面,页面进行调用。页面只负责得到数据、显示数据,逻辑都写在store里面。
2.全局确定一个store,一级模块可确定一个store,最后进行合并(参考redux的合并),通过inject传递给各个页面。页面可通过调用store的方法进行修改全局的store。
一、安装
yarn add mobx --save
yarn add mobx-react --save
yarn add babel-plugin-syntax-decorators --save
yarn add babel-plugin-transform-decorators-legacy --save
.babelrc 文件配置 babel 插件
{
"presets": [
"react-native",
],
'plugins': [
'syntax-decorators',
'transform-decorators-legacy'
]
}
二、单个页面的数据存放、修改(无需this.state = {...}
、this.setState({...})
)
import React, {Component} from 'react';
import {StyleSheet, Text, View, TextInput} from 'react-native';
import {observable, configure, toJS} from 'mobx'
import {observer} from 'mobx-react'
// 是否采用严格模式
configure({ enforceActions: "observed" }) //false==>"never" true==>"observed" strict==>"always"
// 本页数据源
const myStore = observable({
userName: "尼古拉斯",
userAge: 18,
userSex: 0, // 0 男 1 女
/**
* 修改年龄
* age 要修改的年龄
*/
changeUserAge(age) {
this.userAge = age;
},
/**
* 修改姓名
* age 要修改的年龄
*/
changeUserName(name) {
this.userName = name;
}
},{
changeUserName: action,
changeUserAge: action
})
@observer
export default class App extends Component {
componentDidMount(){
console.log('myStore: ', toJS(myStore));
}
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome to React Native!</Text>
<Text>userName: {myStore.userName}</Text>
<Text>userPsd: {myStore.userPsd}</Text>
<View style={{flexDirection: "row", marginTop: 20}}>
<Text style={{width: 100}}>你的名字:</Text>
<TextInput value={String(myStore.userName)} onChangeText={(value)=>{
// 调用方法直接修改姓名
myStore.changeUserName(value);
}}/>
</View>
</View>
);
}
}
三、全局数据的存放、修改、即时更新
使用Provider
/** @format */
import {AppRegistry} from 'react-native';
import App from './App';
import AppState from './AppState';
import {name as appName} from './app.json';
import React, {Component} from 'react';
import {Provider} from 'mobx-react';
import {observable, extendObservable, action, decorate, runInAction} from 'mobx'
import {inject, observer} from 'mobx-react'
class RootStore {
constructor() {
this.userStore = new UserStore(this)
this.todoStore = new TodoStore(this)
// 给 userStore 添加 observable 的属性
extendObservable(this.userStore, {
userName: '尼古拉斯-root',
userAge: '18-root',
userSex: '男-root'
});
// 给 todoStore 添加 observable 的属性
extendObservable(this.todoStore, {
todoList: [
"吃饭",
"睡觉",
"看书"
]
});
}
}
class UserStore {
constructor(rootStore) {
this.rootStore = rootStore
}
// 修改用户名
changeRootUserName(name){
// runInAction 在这里面写 可以修改 observable 修饰的变量
runInAction(()=>{
this.userName += name
})
}
}
class TodoStore {
constructor(rootStore) {
this.rootStore = rootStore
}
// 修改list
changeTodoList(list){
// runInAction 在这里面写 可以修改 observable 修饰的变量
runInAction(()=>{
this.todoList = list
})
}
}
const colors = observable({
foreground: '#000',
background: '#fff'
});
const rootStore = new RootStore();
class Root extends Component {
render() {
console.log('rootStore=====', rootStore)
return (
// 可以添加其他的属性
<Provider rootStore={rootStore} colors={colors}>
<App />
</Provider>
);
}
}
AppRegistry.registerComponent(appName, () => Root);
// 通过 inject 获取传递过来的store,inject("rootStore","colors",......)
// 注意: 从 mobx-react 4开始,注入 stores 的语法发生了变化,应该一直使用 inject(stores)(component) 或 @inject(stores) class Component...。 直接传递 store 名称给 observer 的方式已废弃。
const App = inject("rootStore","colors")(observer(class App extends Component {
componentDidMount(){
console.log('myStore: ', toJS(myStore));
console.log('this.props.rootStore: ', toJS(this.props.rootStore));
console.log('this.props.colors: ', toJS(this.props.colors));
}
render() {
return (
<View style={styles.container}>
<View>
// 获取 全局的变量
<Text>rootName: {this.props.rootStore.userStore.userName}</Text>
{
this.props.rootStore.todoStore.todoList.map((value, index)=>{
return <Text key={index}>todo: {value}</Text>
})
}
<AppUserNameItem data={myStore.userName} store={myStore}/>
<AppUserAgeItem data={myStore.userAge} store={myStore}/>
<TouchableOpacity onPress={()=>{
// 直接修改全局的变量
this.props.rootStore.userStore.changeRootUserName('123')
}}>
<Text>点击修改rootUserNmae</Text>
</TouchableOpacity>
<TouchableOpacity onPress={()=>{
// 直接修改全局的变量
this.props.rootStore.todoStore.changeTodoList(['玩游戏','聊天','逛街','唱歌'])
}}>
<Text>点击修改TodoList</Text>
</TouchableOpacity>
</View>
</View>
);
}
}))
❌(不会解决🙄)使用@observable
会出现
error: bundling failed: TypeError: Property right of AssignmentExpression expected node to be of a type ["Expression"] but instead got null