目前已經可以做到怎麼新增待辦事項,不過我們都還沒讓其顯示在畫面上,所以今天要來示範如何在 App 中使用 FlatList。
每個工具都有其特定的用途,就像你不會用錘子來切水果一樣。在展示長列表時,FlatList 是你的最佳工具。為什麼呢?
FlatList 是 React Native 所提供的列表元件,他有以下的優點:
讓我們在 src/componsnts 中新增一個 List.js。
由於這裡顯示的資料,是來自於我們昨天所建立的 context 狀態,所以要使用 useContetx 來讀取來自 Store 的資料。
import { useContext } from 'react'
import { SafeAreaView, FlatList, View, Text, StyleSheet } from 'react-native'
import { Store } from '../store'
前面提到 FlatList 可以自定義顯示的部分,所以第一步要先建立一個元件,使其顯示在列表中,有點像是在網頁中的 <li>。
const Item = ({ item }) => (
  <View>
    <Text>{item.text}</Text>
  </View>
)
接著就可以使用 FlatList 了。
const List = () => {
  const { state, dispatch } = useContext(Store)
  const renderItem = ({ item }) => <Item item={item} />
  return (
    <SafeAreaView>
      <FlatList
        data={state.todos}
        renderItem={renderItem}
        keyExtractor={(item) => item.id}
      />
    </SafeAreaView>
  )
}
export default List
解釋一下 FlatList 中的參數:
useContext 中的 state 獲取待辦事項列表。Item 元件來實現。最後就可以在 App.js 使用 List 這個元件:
import List from './src/components/List'
export default function App() {
  return (
    <StoreProvider>
      <SafeAreaView style={styles.container}>
        <Head />
        <List />
        <StatusBar style='auto' />
      </SafeAreaView>
    </StoreProvider>
  )
}
最後我們再稍微美化一下 List 的樣式,你可以自己設計樣式,或者也可以按照我的樣式:
const Item = ({ item }) => (
  <View style={styles.item}>
    <View>
      <Text style={styles.itemText}>{item.text}</Text>
    </View>
  </View>
)
const List = () => {
  // 程式碼省略
  return (
    <SafeAreaView style={styles.container}>
      <FlatList
        data={state.todos}
        renderItem={renderItem}
        keyExtractor={(item) => item.id}
      />
    </SafeAreaView>
  )
}
const styles = StyleSheet.create({
  container: {
    width: '90%',
    marginTop: 20
  },
  item: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    width: '100%',
    marginVertical: 10
  },
  checkboxAndText: {
    flexDirection: 'row',
    alignItems: 'center'
  },
  itemText: {
    fontSize: 18,
    fontWeight: '500',
    marginLeft: 10,
    color: '#fff',
  },
  finishItemText: {
    textDecorationLine: 'line-through'
  },
  emptyWrap: {
    alignItems: 'center',
    justifyContent: 'center'
  },
  emptyText: {
    color: '#fff',
    fontSize: 18,
    fontWeight: '500'
  },
  emptyImage: {
    width: 200,
    height: 200
  }
})
最後展示一下畫面,明天見👋。
