react-native init ReactNativeMobxTodo
cd ReactNativeMobxTodo
react-native start
react-native run-android
yarn add babel-plugin-transform-decorators-legacy mobx mobx-react mobx-remotedev -D
{ | |
"presets": ["react-native"], | |
"plugins": ["transform-decorators-legacy"] | |
} |
react-native init ReactNativeMobxTodo
cd ReactNativeMobxTodo
react-native start
react-native run-android
yarn add babel-plugin-transform-decorators-legacy mobx mobx-react mobx-remotedev -D
import React, { Component } from 'react'; | |
import { AppRegistry } from 'react-native'; | |
import App from './src/App'; | |
import TodoStore from './src/TodoStore'; | |
const todoStore = new TodoStore(); | |
export default class ReactNativeMobxTodo extends Component { | |
render() { | |
return ( | |
<App todoStore={todoStore} /> | |
); | |
} | |
} | |
AppRegistry.registerComponent('ReactNativeMobxTodo', () => ReactNativeMobxTodo); |
import React, { Component } from "react"; | |
import { observer } from "mobx-react"; | |
import { | |
Button, | |
FlatList, | |
ScrollView, | |
StyleSheet, | |
Switch, | |
Text, | |
TextInput, | |
View | |
} from "react-native"; | |
@observer | |
export default class App extends Component { | |
constructor(props) { | |
super(props); | |
this.state = { task: "" }; | |
} | |
handleChange = (text) => { | |
this.setState({ task: text }); | |
} | |
addTodo = () => { | |
console.log(this.state.task); | |
this.props.todoStore.addTodo(this.state.task); | |
this.setState({ task: "" }); | |
} | |
renderItem = (todo) => { | |
console.log(todo); | |
return ( | |
<View style={ styles.listItem } > | |
<Switch | |
value={ todo.completed } | |
/> | |
<Text>{ todo.task }</Text> | |
</View> | |
); | |
} | |
render() { | |
const data = this.props.todoStore.todos.map((todo, i) => { | |
return { | |
...todo, | |
key: i | |
}; | |
}); | |
return ( | |
<ScrollView style={{ flex: 1 }} > | |
<View style={ styles.container } > | |
<View> | |
<Text style={ styles.header } >Todo Report</Text> | |
<Text style={ styles.text } >{ this.props.todoStore.report }</Text> | |
</View> | |
<View> | |
<Text style={ styles.header } >Todo Form</Text> | |
<TextInput | |
value={ this.state.task } | |
onChangeText={ this.handleChange } /> | |
<Button title="add" onPress={ this.addTodo } /> | |
</View> | |
<View> | |
<Text style={ styles.header } >Todo List</Text> | |
<FlatList | |
data={ data } | |
renderItem={ (item) => this.renderItem(item.item) } /> | |
</View> | |
</View> | |
</ScrollView> | |
); | |
} | |
} | |
const styles = StyleSheet.create({ | |
container: { | |
flex: 1, | |
alignItems: "center", | |
backgroundColor: "#F5FCFF", | |
}, | |
header: { | |
fontSize: 24, | |
textAlign: "center", | |
margin: 10, | |
}, | |
text: { | |
textAlign: "center", | |
}, | |
listItem: { | |
flexDirection: "row" | |
} | |
}); |
import { observable, action, computed } from 'mobx'; | |
export default class TodoStore { | |
@observable todos = []; | |
@observable pendingRequests = 0; | |
@computed get completedTodosCount() { | |
return this.todos.filter(todo => todo.completed === true).length; | |
} | |
@computed get report() { | |
if (this.todos.length === 0) { | |
return "<none>"; | |
} else { | |
return `Next todo: "${this.todos[0].task}". ` + | |
`Progress: ${this.completedTodosCount}/${this.todos.length}`; | |
} | |
} | |
@action addTodo(task) { | |
this.todos.push({task, completed: false, assignee: null}); | |
} | |
} |