第 20 天~
走到了三分之二了~!!!
好激動阿!!
再接再厲~ 加油!
昨天把 To Do List 的邏輯全都完成了,
我們今天來 聊聊 關於 compound component (合成元件)
當我們在開發時,總會碰上幾個狀況:
在這種時候,我們會希望能把這些獨立出來,封裝
成一個 component ,
以 To Do List
為例的話,我們會拆分成哪些 component 呢?
Add
& Search
& Complete All
這三個按鈕,不管是功能還是外型都是一樣的,
那我們就可以把它封裝成 FeatureButton
,
功能 :
const styles = StyleSheet.create({
root: {
flex: 1,
backgroundColor: '#d9d9d9',
borderColor: '#7c7c7c',
borderWidth: 1,
padding: 5,
},
text: {
textAlign: 'center',
color: '#555',
},
});
function FeatureButton({ text, onPress, ...etc }) {
return (
<TouchableOpacity style={styles.root} onPress={onPress} {...etc}>
<Text style={styles.text}>{text}</Text>
</TouchableOpacity>
);
}
因為內部沒有獨立邏輯,我們可以只需要使用 functional component
就好,
藉由 props 把所需的資訊傳入,
在 FlatList 的 renderItem 部分,
我們也可以把它封裝成一個 component 來增加閱讀性,
因為封裝起來,我們有些地方需要做改變,
const styles = StyleSheet.create({
root: {
paddingVertical: 17,
flexDirection: 'row',
},
odd: {
backgroundColor: '#eee',
},
even: {
backgroundColor: '#f9f9f9',
},
doneBackground: {
backgroundColor: '#888',
},
text: {
marginLeft: 10,
},
doneText: {
color: '#fff',
textDecorationLine: 'line-through',
},
tickArea: {
marginHorizontal: 10,
transform: [{ rotate: '45deg' }],
height: 14,
width: 8,
},
tick: {
borderBottomColor: '#fff',
borderRightColor: '#fff',
borderBottomWidth: 1,
borderRightWidth: 1,
},
});
function ToDoItem({ text, isDone, isEven, onPress }) {
const backgroundColorStyle = isEven ? styles.even : styles.odd;
return (
<TouchableOpacity
style={[
styles.root,
backgroundColorStyle,
isDone && styles.doneBackground,
]}
onPress={onPress}>
<View style={[styles.tickArea, isDone && styles.tick]}></View>
<Text style={[styles.text, isDone && styles.doneText]}>{text}</Text>
</TouchableOpacity>
);
}
那外部使用就是這樣:
<FlatList
data={list.filter((item) => item.text.includes(filterKey))}
renderItem={({ item, index, separators }) => {
const isEven = index % 2 === 0;
const isDone = item.status === 'done';
return (
<ToDoItem
isEven={isEven}
isDone={isDone}
text={item.text}
onPress={this.changeItemStatus(item.id)}
/>
);
}}
keyExtractor={(item) => item.id}
/>