初探MobX之TodoList【多选】【反选】
1. 首先说下我学这玩意儿的目的===>【最近突然想好好提升下技术,所以啥玩意er都学】
嗯,他是简单、可扩展的状态管理
2. 其次说下我遇到的坑之===>【箭头函数】
之前做项目一直没太注意这个东西,一直以为箭头函数和普通的函数除了一个长得帅一点儿之外,没什么区别,所以就一直看心情随便用的。这次终于。。踩坑了。具体细节可以看大神的详细讲解, 附大神讲解链接
想看比较直白【肤浅】 的知识请看下面这张图片。
当我在onclick中需要去屌(diao)用_handleClick()中的setState()方法时,妈蛋给我报了个this.setState is not a function。嗯,果断是知识的匮乏把我给坑了,换上箭头函数之后一切正常。
3. 废话说的差不多了===>【上代码】
import React, {Component} from 'react';
import {
View,
Text,
StyleSheet,
TouchableOpacity,
TextInput, AppState,
} from 'react-native';
import {
Checkbox,
} from 'teaset'
import {AppColor, AppSize, scaleWidthSize, scaleHeightSize, DeviceWidth, scaleFontSize} from '../../util/StyleUtils';
import {observable, action, computed} from 'mobx';
import {observer} from 'mobx-react';
class Todo {
id = Math.random();
@observable title = '';//条目的标题
@observable checked = false;//是否被选中
constructor(title) {
this.title = title;
}
//单条数据反选
@action.bound toggle() {
this.checked = !this.checked;
}
//置为选中
@action.bound setChecked() {
this.checked = true;
}
//置为全部不选中
@action.bound setUnChecked() {
this.checked = false;
}
}
class Store {
@observable todos = [];
@action.bound createTodo(title) {
//向todos数组当开头插入一条新数据
this.todos.unshift(new Todo(title));
}
@computed get uncheckedItemCount() {
//返回未选中的条目数量
return this.todos.filter(todo => !todo.checked).length;
}
@computed get checkedItemCount() {
//返回被选中对条目数量
return this.todos.filter(todo => todo.checked).length;
}
@computed get allItemCount() {
//返回所有条目数量
return this.todos.length;
}
}
let store = new Store();
@observer
export class TodoItem extends Component {
//单条数据反选
_handleToggle = (e) => {
this.props.todo.toggle();
};
render() {
let todo = this.props.todo;
return <View style={styles.item} key={todo.id}>
<Checkbox
size='lg'
checked={todo.checked}
onChange={this._handleToggle}
/>
<Text>{todo.title}</Text>
</View>;
}
}
@observer
export default class TodoList extends Component {
constructor(props) {
super(props);
this.state = {
inputValue: ''
}
}
//TextInput提交时,按回车时,触发此函数
_handleSubmit = (e) => {
e.preventDefault();
// let store = this.props.store;
let inputValue = this.state.inputValue;
store.createTodo(inputValue);
this.setState({inputValue: ''})
};
//点击事件里面 setState 时会使this重新定义,所以在点击的函数里面使用this.setState()时会报错this.setState not a function,因此需要提前给点击事件的函数绑定this
// _handleTextChange = this._handleTextChange.bind(this);
//文本框文字更改时触发函数
//注意,为了使上下文this准确,这里使用箭头函数。否则需要手动绑定bind(this);
_handleTextChange = (e) => {
let inputValue = e.nativeEvent.text;
this.setState({
inputValue: inputValue,
});
};
//全选方法
_handleAllCheck = (e) => {
store.todos.map(todo => {
todo.setChecked();
})
}
;
//全不选方法
_handleAllUnCheck = (e) => {
store.todos.map(todo => {
todo.setUnChecked();
})
};
//反选方法
_handleToggle = (e) => {
store.todos.map(todo => {
todo.toggle();
})
};
componentWillUnmount() {
//退出时清理store数据
}
render() {
// let {store} = this.props.store;
let todos = store.todos;
return (
<View style={styles.root}>
<View style={styles.item}>
<TouchableOpacity
style={styles.button}
onPress={() => {
this._handleAllCheck()
}}
>
<Text style={{color: 'white'}}>全选</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => {
this._handleAllUnCheck()
}}
>
<Text style={{color: 'white'}}>全不选</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => {
this._handleToggle()
}}
>
<Text style={{color: 'white'}}>反选</Text>
</TouchableOpacity>
</View>
<TextInput style={styles.item}
onSubmitEditing={this._handleSubmit}
blurOnSubmit={false}
onChange={this._handleTextChange}
value={this.state.inputValue}
placeholder={'请输入要添加的新条目'}/>
{
todos.map(todo => {
return <TodoItem todo={todo}/>
})
}
<Text style={styles.countText}>总共{store.allItemCount}条数据</Text>
<Text style={styles.countText}>{store.checkedItemCount}条被选中</Text>
<Text style={styles.countText}>{store.uncheckedItemCount}条未被选中</Text>
</View>
);
}
}
const styles = StyleSheet.create({
root: {
flex: 1,
paddingHorizontal: scaleWidthSize(20),
},
item: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
backgroundColor: '#ffffff',
marginTop: scaleHeightSize(20),
padding: scaleWidthSize(10),
height: scaleHeightSize(100),
width: '100%'
},
button: {
width: scaleWidthSize(150),
height: scaleHeightSize(50),
borderRadius: scaleHeightSize(50),
backgroundColor: 'black',
alignItems: 'center',
justifyContent: 'center'
},
countText: {
marginTop: scaleHeightSize(30),
color: 'red',
fontSize: scaleFontSize(24)
}
});
嗯,6点半该下班了,突然不想讲了,再见。✌️
(打不到我吧我就是这么强大)