本教程內容和https://zhiwehu.gitbooks.io/react-native/content/ 同步更新。
使用TextInput
接下來,我們將使用TextInput作為todo的輸入框,將todo item加到todo list里。
首先,思考一下我們要怎么對數據進行管理。對于整個app來說,我們需要有2個狀態(state)值,一個用于存儲當前正在輸入的todo,一個用于存儲所有的todo item,這2個狀態在app初始狀態的時候,都是空的(對于todo list值來說,后面我們需要導入之前持久存儲的數據,這個我們后面再講),當我們在TextInput中輸入字符的時候,會更新當前正在輸入的todo value;當我們按下鍵盤上的"done"按鈕的時候,會將這個todo value增加到todo list里,同時將這個value清空。
2個state
- value: 存儲當前正在輸入的todo,TextInput onChangeText事件會更新這個狀態
- items: 存儲所有todo list,TextInput onSubmitEditing事件會更新這個狀態,同時將value狀態設置為空。
header.js
TextInput是需要放在Header里面的,以下是header.js的新代碼:
// 引入React和Component
import React, {Component} from "react";
// 引入Text,顯示文字
import {View, Text, StyleSheet, TextInput} from "react-native";
// 定義Header類,這個類是Component的子類
class Header extends Component {
/*
實現Header類的render方法,這個方法返回一個View,顯示Footer
*/
render() {
return (
<View style={styles.header}>
<TextInput
placeholder="什么需要做?"
value={this.props.value}
onChangeText={this.props.onChange}
onSubmitEditing={this.props.onAddItem}
blurOnSubmit={false}
returnKeyType="done"
style={styles.input}
/>
</View>
);
}
}
// 創建StyleSheet
const styles = StyleSheet.create({
header: {
paddingHorizontal: 16,
flexDirection: "row",
justifyContent: "space-around",
alignItems: "center"
},
input: {
flex: 1,
height: 50
}
});
// 導出這個模塊,供外部調用
export default Header;
我們可以看到,我們在Header是創建了一個TextInput,并且把值和處理方法都放在Header的props中傳給了這個TextInput,也就是意味著我們不需要在Header中寫代碼來處理app的邏輯,這部分代碼我們統一放在app.js里來做。
我們對Header傳了三個props:
- value,是一個值,就是app用于存儲當前正在輸入的todo value
- onChange,一個回調函數,用于TextInput onChangeText的時候,更新app.state.value
- onAddItem,一個回調函數,當TextInput onSubmitEditing(提交)的時候,更新app.state.items,并將app.state.value設置為空。
接下來我們在app.js里實現這部分代碼。
初始化state
在App類的構造方法里,初始化state
// 構造方法,初始化state
constructor(props) {
super(props);
// 初始化2個狀態
this.state = {
value: "",
items: []
};
}
TextInput onSubmitEditing回調函數
/*
傳給Header.TextInput.onSubmitEditing的回調函數
更新this.state.items
設置this.state.value為空
*/
handleAddItem() {
if (!this.state.value) return;
// 創建一個新的items,從this.state.items里copy現有的數據,再增加一個新的
const newItems = [
...this.state.items,
{
key: Date.now(),
text: this.state.value,
complete: false
}
];
// 更新state
this.setState({
items: newItems,
value: ""
});
}
我并沒有直接往this.state.items里增加一條新數據,而是重新創建了一個新的items,從老的items里copy了原有數據,并且增加了一條新數據。這樣做的好處是讓react native的shouldComponentUpdate性能更好,從而更加快速的知道一個組件是否有狀態變化,從而重新render數據。詳情參考:https://facebook.github.io/react/docs/optimizing-performance.html
傳值給Header props
接下來就是給Header props傳值了
<Header
value = {this.state.value}
onAddItem = {this.handleAddItem.bind(this)}
onChange = {(value) => this.setState({value})}
/>
運行結果如下:

當然,現在按下Done增加一個新的todo,我們的app沒有任何變化,我們將在下一篇中講解如果顯示todo list。
本節代碼:https://github.com/zhiwehu/todo/tree/second