1.能在Header中输入文字
首先,给Header
上加一个输入文字的TextInput
部分,并加上对应的style。
关于TextInput
,可以看 官方文档 写的很详细。常用的事件有:onChangeText
读用户输入,onSubmitEditing
提交键入和 onFocus
获得焦点。
header.js
import { View, Text, StyleSheet, TextInput } from 'react-native';
class Header extends Component {
render() {
return (
<View style={styles.header}>
<TextInput
placeholder="What needs to be done?"
blurOnSubmit={false}
returnKeyType="done"
style={styles.input}
/>
</View>
);
}
}
const styles = StyleSheet.create({
header: {
paddingHorizontal: 1,
flexDirection: "row",
justifyContent: "space-around",
alignItems: "center",
},
input: {
flex: 1,
height: 50
}
})
注意:textinput
必须要写明height
,不然就默认高度为0,所以看不到。刷新模拟器看下效果,header
部分出现了placeholder的内容。
2.能够添加todo item
2.1 constructor和state
下面回到app.js
,写一个constructor。在 constructor 中可以定义state的结构。
现在state只需要两个参数:value存储当前输入的todo item内容;items数组,存储所有的todo items。
通过this.state.value
,this.state.items
可以读取。
constructor(props) {
super(props);
this.state = {
value: '',
items: []
}
}
2.2 在header中输入一条todo item,并将该item添加到this.state.items数组中
通过handleAddItem
这个function来实现,这样的function被称作event handler,命名一般遵循类似的handle+v+n的结构,后面还能看到很多。
handleAddItem() {
if(!this.state.value) return;
const newItems = [
...this.state.items,
{
key: Date.now(),
text: this.state.value,
complete: false
}
]
this.setState({
items: newItems,
value: ''
})
}
注意:
-
...this.state.items
的这三个点是ES6语法,叫Spread,意思是用原来的this.state.items
加上新的object构造一个新数组并赋值给this.state.items
。 - 当需要改变state中的值的时候,绝对不能直接赋值给state,必须使用
this.setState
这个方法。
将这个function跟Header
wire起来:
<Header
value={this.state.value}
onAddItem={this.handleAddItem}
onChange={(value) => this.setState({ value })}
/>
需要注意的是一个component中所有的异步function都要在constructor中bind,不然会报错。
constructor(props) {
super(props);
this.state = {
value: '',
items: []
}
/* 不要忘了在constructor中bind method */
this.handleAddItem = this.handleAddItem.bind(this);
}
进入header.js
文件,用this.props
就能使用父元素传入的参数
<TextInput
value={this.props.value}
onChangeText={this.props.onChange}
onSubmitEditing={this.props.onAddItem}
...
/>
现在刷新模拟器,可以输入一些文字,点击键盘上的完成,input栏会立刻清空,输入的内容被添加到items数组。
3. 写toggle complete button
这里要用到 TouchableOpacity。虽然名字很复杂,其实就是可以点击的button, 用onPress
事件触发点击后动作。
这个按钮的功能就是,点击后,将当前所有的todo item的状态都切换为已完成,若再次点击,则全部变成未完成。
header.js
import { ... TouchableOpacity } from 'react-native';
render() {
return (
<View style={styles.header}>
<TouchableOpacity onPress={this.props.onToggleAllComplete}>
<Text style={styles.toggleIcon}>{String.fromCharCode(10003)}</Text>
</TouchableOpacity>
...
);
}
}
...
toggleIcon: {
fontSize: 30,
color: "#CCC"
}
效果如下,
toggleAllComplete.png下面来实现,点击这个勾能toggleAllComplete的逻辑:
首先需要在state中添加一个allComplete
初始值:
app.js
this.state = {
allComplete: false,
value: '',
items: ~[]~
}
event handler function如下:
handleToggleAllComplete() {
const complete = !this.state.allComplete;
const newItems = this.state.items.map((item) => ({
...item,
complete
}))
console.table(newItems);
this.setState({
items: newItems,
allComplete: complete
})
}
console.table类似console.log,方便的是可以以table格式展示结果,易于查看。
(调试方法见最后)
<Header
...
onToggleAllComplete={this.handleToggleAllComplete}
/>
别忘了要bindthis.handleToggleAllComplete = this.handleToggleAllComplete.bind(this);
react Native调试方法
- cmd+D呼出如下图菜单:
- 选择debug JS remotely,就可以用浏览器来调试和查看console结果,非常方便。现在在模拟器里添加Task1,Task2。然后点击✔️按钮,看到浏览器的console里面出现了结果:
如果再点击一次✔️按钮:
33.png
网友评论