Finally came to this article, the previous content is actually to let us understand this demo, so we use MOBX to manage the data and state, we can better understand the meaning of our use of MOBX.
In the previous two code, we can see that in the Todoapp class, not only the UI-related code is included, but also the operation implementation (Itemmodel and Listmodel) of the model, and the operation of the list item is implemented in the Todoapp class.
Let's use iOS development as an analogy: it's like putting all the business logic (including the cell's internal logic) in a VC, and if the functionality gets complicated, our code becomes more and more difficult to maintain because there is no clear structure. MOBX as a library of the same type as redux, it makes it easy for us to peel out model and related business logic (in achieving this we are also far from the state of the transfer and internal management, which makes us comfortable a lot, after all, I personally look at the state of the design concept, although relatively good, But from the actual application point of view is very troublesome, to code writing and maintenance have brought many problems, compared to see Vue is more simple and pragmatic.
Introduction from the official website: It makes state management simple and extensible through transparent function-responsive programming (transparently applying functional reactive PROGRAMMING-TFRP).
So from a pragmatic standpoint, the meaning of using MOBX is to make the code clearer, simpler, and easier to scale and maintain.
Here's a look at our implementation: The reconstructed demo is divided into 3 classes, two more than before: Todoitem, todolist; from an oop point of view this is natural. We need a model for the list item, we also need a list as the data source for the list, and it can also host the encapsulation of the list model operation.
Todoitem:
Import {Observable, action, computed} from ' MOBX ';
Import {usestrict} from ' MOBX ';
Usestrict (true);
Todoitem model.
Export Default class Todoitem
{
//provides a constructor method to facilitate the creation of an object, which is created by default from the constructor method.
Constructor (text,done,index) {
this.done = Done?done:false;
This.text = Text?text: ';
this.id = index;
This.key = index;
}
@observable done;
@observable text;
ID;
Key;
Use action to manipulate the semantics more clearly.
@action Toggle () {
console.log (' Toggle in Item, done= ' +this.done)
this.done =!this.done;
Console.log (' 2-toggle in Item, done= ' +this.done)
}
}
Provides a constructor, as well as a toggle operation to change the done state.
ToDoList:
Import {Observable, action, computed} from ' MOBX ';
Import {usestrict} from ' MOBX ';
Usestrict (TRUE);
Import {reaction} from ' Mobx/lib/api/autorun ';
Import Todoitem from './todoitem '; ToDoList class;
Data Model + actions!
Class ToDoList {//initialization gives a record; constructor methods are not provided here.
@observable list = [New Todoitem (' Todo Item #1 ', false, 1)];
@observable Ishidedone = false;
@action Addtodo () {Const NEWTODO = This.maketodo ();
This.list = [Newtodo, ... this.list];
} @action Maketodo (index, Isdone) {const-id = index index:this.list.length+1;
Console.log (' isdone= ' +isdone) var newitem = new Todoitem (' Todo Item # ' + id,isdone, id);
return newitem;
} @action Togglehidden () {this.ishidedone =!this.ishidedone; @computed get Shownlist () {if (This.ishidedone) {return This.list.filter (item) =&G T
{return!item.done;
});
} else {console.log (this.list) return this.list;
}} const Sharedlist = new ToDoList ();
Export default sharedlist; You need to use this method to export multiple shares to ensure that there is only one instance; In our scenario, it's OK to use it.
Provides a number of action; This is not a pure model, but very practical. A computed value is also provided for datasource switching between the two states.
App.js:
Import react, {Component, proptypes} from ' react ' import {appregistry, StyleSheet, View, Text,
Image, Button, TextInput, ListView, Switch, Touchableopacity, flatlist} from ' React-native '
Import {observable} from "MOBX";
Import {Observer} from ' Mobx-react/native ';
Import sharedlist from './stores/todolist ';
@observer class Todoapp extends Component {constructor (props) {super (props);
Add a record Props.list.addTodo (); Render () {//Here is observer wrapped, very critical. See here://https://github.com/sangka/mobx-docs-cn/blob/master/docs/best/react.md#
Mobx-will only track data access for-observer-components if the data is directly accessed via-render-const ITEMRENDERER = Observer (({item, index}) => ( <view Style={styles.todo} key={item.id}> <View> <switch Onvaluechang e={() => item.toggle ()} Value={item.done}/> </View> <view&Gt
<Text>{item.text}</Text> </View> </View>))
Return (<view Style={styles.container} > <view style={styles.options}>
<touchableopacity onpress={() => This.props.list.addTodo ()} style={styles.add}> <text>+ Add a todo</text> </TouchableOpacity> <view style={s
tyles.hide}> <text>hide done</text> <switch onvaluechange={(value) => This.props.list.toggleHidden ()} value={this.props
. List.ishidedone}/> </View> </View> <flatlist Data={this.props.list.shownlist} renderitem={({item, index}) => <itemrendererItem={item} index={index}/>/> </View>); } Const STYLES = Stylesheet.create ({container: {flex:1, backgroundcolor: ' #F5FCFF ',}, a DD: {flex:1, padding:10}, Hide: {flex:1, flexdirection: ' Row ', align Items: ' Center ', justifycontent: ' Space-around '}, Options: {flexdirection: ' Row ', margin Top:50, marginbottom:30}, TODO: {flex:1, flexdirection: ' Row ', MarginBottom:
10}});
Export default class App extends React.component {render () {return <todoapp list={sharedlist}/>; }
}
You can see here we've basically done all the work with jsx and stylesheet, and this class is closer to a pure view, which carries the object of MOBX observation in This.props.list. We just call the corresponding model method at the right time, so the structure will make you feel comfortable.
The problem with the only trouble is:
CONST ITEMRENDERER = Observer ({item, index}) => (
<view Style={styles.todo} key={item.id}>
<view& gt;
<switch onvaluechange={() => item.toggle ()} Value={item.done}/>
</View>
<View>
<Text>{item.text}</Text>
</View>
</View>
)
)
I was originally bound by the arrow function and the RenderItem method, but found that the switch was not displayed correctly. After debugging and documentation lookup, code review I found the answer:
If this is directly binding the RenderItem callback method, then our @observer in the Todoapp class is not actually able to observe the observations within the method. Since the implementation of this method is actually done in flatlist, we have no way to transform the Flatlist code. So the solution is simple, MOBX gives us two choices:
Https://github.com/SangKa/mobx-docs-cn/blob/master/docs/best/react.md#mobx
We used a more intuitive look, using observer to wrap up the arrow functions that created the list item so that we could observe the observations inside the method, and when the value changed we could trigger the render normally.
PS: Read this article do not understand the place please feel free to check the MOBX Official document basic concepts.
Http://cn.mobx.js.org/best/react.html
This is just a simple start, and the strength of the MOBX depends on how you use it, and its concept and the power of implementation may be far more than you can imagine.
Attached (GitHub link, if help you welcome to a star): Https://github.com/dustturtle/RNMobXTodoDemo