1.能在Header中輸入文字
首先,給Header
上加一個(gè)輸入文字的TextInput
部分,并加上對(duì)應(yīng)的style响迂。
關(guān)于TextInput
蹋笼,可以看 官方文檔 寫(xiě)的很詳細(xì)。常用的事件有:onChangeText
讀用戶輸入蜕该,onSubmitEditing
提交鍵入和 onFocus
獲得焦點(diǎn)犁柜。
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
必須要寫(xiě)明height
,不然就默認(rèn)高度為0堂淡,所以看不到馋缅。刷新模擬器看下效果,header
部分出現(xiàn)了placeholder的內(nèi)容淤齐。
2.能夠添加todo item
2.1 constructor和state
下面回到app.js
,寫(xiě)一個(gè)constructor股囊。在 constructor 中可以定義state的結(jié)構(gòu)。
現(xiàn)在state只需要兩個(gè)參數(shù):value存儲(chǔ)當(dāng)前輸入的todo item內(nèi)容更啄;items數(shù)組稚疹,存儲(chǔ)所有的todo items。
通過(guò)this.state.value
,this.state.items
可以讀取祭务。
constructor(props) {
super(props);
this.state = {
value: '',
items: []
}
}
2.2 在header中輸入一條todo item内狗,并將該item添加到this.state.items數(shù)組中
通過(guò)handleAddItem
這個(gè)function來(lái)實(shí)現(xiàn),這樣的function被稱(chēng)作event handler义锥,命名一般遵循類(lèi)似的handle+v+n的結(jié)構(gòu)柳沙,后面還能看到很多。
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
的這三個(gè)點(diǎn)是ES6語(yǔ)法拌倍,叫Spread赂鲤,意思是用原來(lái)的this.state.items
加上新的object構(gòu)造一個(gè)新數(shù)組并賦值給this.state.items
。 - 當(dāng)需要改變state中的值的時(shí)候柱恤,絕對(duì)不能直接賦值給state数初,必須使用
this.setState
這個(gè)方法。
將這個(gè)function跟Header
wire起來(lái):
<Header
value={this.state.value}
onAddItem={this.handleAddItem}
onChange={(value) => this.setState({ value })}
/>
需要注意的是一個(gè)component中所有的異步function都要在constructor中bind梗顺,不然會(huì)報(bào)錯(cuò)泡孩。
constructor(props) {
super(props);
this.state = {
value: '',
items: []
}
/* 不要忘了在constructor中bind method */
this.handleAddItem = this.handleAddItem.bind(this);
}
進(jìn)入header.js
文件,用this.props
就能使用父元素傳入的參數(shù)
<TextInput
value={this.props.value}
onChangeText={this.props.onChange}
onSubmitEditing={this.props.onAddItem}
...
/>
現(xiàn)在刷新模擬器寺谤,可以輸入一些文字仑鸥,點(diǎn)擊鍵盤(pán)上的完成,input欄會(huì)立刻清空变屁,輸入的內(nèi)容被添加到items數(shù)組眼俊。
3. 寫(xiě)toggle complete button
這里要用到 TouchableOpacity。雖然名字很復(fù)雜粟关,其實(shí)就是可以點(diǎn)擊的button, 用onPress
事件觸發(fā)點(diǎn)擊后動(dòng)作泵琳。
這個(gè)按鈕的功能就是,點(diǎn)擊后,將當(dāng)前所有的todo item的狀態(tài)都切換為已完成获列,若再次點(diǎn)擊谷市,則全部變成未完成。
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"
}
效果如下,
下面來(lái)實(shí)現(xiàn)击孩,點(diǎn)擊這個(gè)勾能toggleAllComplete的邏輯:
首先需要在state中添加一個(gè)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類(lèi)似console.log迫悠,方便的是可以以table格式展示結(jié)果,易于查看巩梢。
(調(diào)試方法見(jiàn)最后)
<Header
...
onToggleAllComplete={this.handleToggleAllComplete}
/>
別忘了要bindthis.handleToggleAllComplete = this.handleToggleAllComplete.bind(this);
react Native調(diào)試方法
- cmd+D呼出如下圖菜單:
- 選擇debug JS remotely创泄,就可以用瀏覽器來(lái)調(diào)試和查看console結(jié)果,非常方便±穑現(xiàn)在在模擬器里添加Task1鞠抑,Task2。然后點(diǎn)擊??按鈕忌警,看到瀏覽器的console里面出現(xiàn)了結(jié)果:
如果再點(diǎn)擊一次??按鈕: