iT邦幫忙

2021 iThome 鐵人賽

DAY 20
0
Modern Web

React Native & Redux 初步探討系列 第 20

Day 20 To Do List - 封裝

  • 分享至 

  • xImage
  •  

第 20 天~

走到了三分之二了~!!!

好激動阿!!

再接再厲~ 加油!

昨天把 To Do List 的邏輯全都完成了,

我們今天來 聊聊 關於 compound component (合成元件)

當我們在開發時,總會碰上幾個狀況:

  • 有相同地方,重複性高
  • 不同邏輯的干擾
  • 結構太多難以閱讀

在這種時候,我們會希望能把這些獨立出來,封裝成一個 component ,

To Do List 為例的話,我們會拆分成哪些 component 呢?

功能按鈕

Add & Search & Complete All 這三個按鈕,不管是功能還是外型都是一樣的,

那我們就可以把它封裝成 FeatureButton

功能 :

  • onPress 按下去事件
  • text 顯示按鈕文字
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 把所需的資訊傳入,

列表 item

在 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}
/>

上一篇
Day 19 To Do List - 加入邏輯 2
下一篇
Day 21 單向資料流
系列文
React Native & Redux 初步探討33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言