第 18 天~
昨天已經把畫面給佈置好了
有了畫面,但是沒有任何的邏輯,所以現在任何操作其實都不會有相關的邏輯
今天我們來把相關的邏輯給建立起來,
react
是以資料邏輯來帶動畫面變化的,
所以必須建立相對應的資料以及邏輯,
來達成我們預期的變化,
來看看我們的需求:
所以我們可以翻譯成:
新增
項目改變
項目狀態
filter
列表改變
列表狀態
顯示
列表從上面的需求看,
我們必須有個地方來保存列表資料,
並且跟著畫面做連動
在這裡我們些把 App component
轉成 class component
class App extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<SafeAreaView style={styles.root}>
<View style={styles.header}>
<Text style={styles.title}>My To Do List</Text>
<TextInput style={styles.input} />
<View style={styles.buttonGroup}>
<TouchableOpacity style={styles.button}>
<Text style={styles.buttonText}>Add</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button}>
<Text style={styles.buttonText}>Search</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button}>
<Text style={styles.buttonText}>Complete All</Text>
</TouchableOpacity>
</View>
</View>
<FlatList
data={list}
renderItem={({ item, index, separators }) => {
const backgroundColorStyle =
index % 2 === 0 ? styles.itemEven : styles.itemOdd;
return (
<TouchableOpacity
style={[styles.item, backgroundColorStyle, styles.itemDone]}>
<View style={[styles.tickArea, styles.tick]}></View>
<Text style={[styles.itemText, styles.doneText]}>
{item.text}
</Text>
</TouchableOpacity>
);
}}
keyExtractor={(item) => item.id}
/>
</SafeAreaView>
);
}
}
並在 state
設定 list 參數,用來保存我們的 todoList 內容
constructor(props) {
super(props);
this.state = {
list:[]
}
}
並把 list 帶入到 render
的 FlatList data
裡
render() {
const {list} = this.state;
return (
<SafeAreaView style={styles.root}>
<View style={styles.header}>
<Text style={styles.title}>My To Do List</Text>
<TextInput style={styles.input} />
<View style={styles.buttonGroup}>
<TouchableOpacity style={styles.button}>
<Text style={styles.buttonText}>Add</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button}>
<Text style={styles.buttonText}>Search</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button}>
<Text style={styles.buttonText}>Complete All</Text>
</TouchableOpacity>
</View>
</View>
<FlatList
data={list}
renderItem={({item, index, separators}) => {
const backgroundColorStyle =
index % 2 === 0 ? styles.itemEven : styles.itemOdd;
return (
<TouchableOpacity
style={[styles.item, backgroundColorStyle, styles.itemDone]}>
<View style={[styles.tickArea, styles.tick]}></View>
<Text style={[styles.itemText, styles.doneText]}>
{item.text}
</Text>
</TouchableOpacity>
);
}}
keyExtractor={item => item.id}
/>
</SafeAreaView>
);
}
這時候畫面會是:
這樣代表我們的資料跟畫面已經初步產生連動了,
接下來我們要可以把在 input
輸入的內容新增到 list
首先我們新增 inputValue state 來保存 input 的內容:
this.state = {
inputValue: '',
list: [],
};
把 inputValue
帶入到 TextInput component
const { list, inputValue } = this.state;
<TextInput style={styles.input} value={inputValue} />;
在 TextInput component
設定 onChangeText
,
onInputChange = (text) => {
this.setState(() => {
return {
inputValue: text,
};
});
};
<TextInput
style={styles.input}
value={inputValue}
onChangeText={this.onInputChange}
/>;
這樣,與 input 的連動就告一段落了,
再來, 我們來定義 todo item 的格式,
來看看 item 的需求:
done
or not done
timestamp
來當做 id 好了所以我們格式大約是,
const item ={
id: 0
text: '',
status: ''// done or not done
}
所以我們建立一個 function 專門控管 item 新增
createToDoItem = () => {
const { inputValue, list } = this.state;
const item = {
id: new Date().getTime(),
text: inputValue,
status: 'not Done',
};
const newList = [...list, item];
this.setState(() => {
return {
inputValue: '',
list: newList,
};
});
};
像上面的程式碼,
我們先把 state
取出 inputValue
& list,
在把 需要新增的 item
放入到 list
,
然後記得把 inputValue , 不然 input 會留住已新增的項目
最後,用 setState
來更新,
最後把 createToDoItem 放入到 Add 的 TouchableOpacity component
的 onPress
<TouchableOpacity style={styles.button} onPress={this.createToDoItem}>
<Text style={styles.buttonText}>Add</Text>
</TouchableOpacity>
那結果會是:
這樣就看到,我們的資料新增
已經跟畫面連動了