跳到主要内容

เนื้อหาภาษาไทย / 泰语内容

系统指南 内容已审核

การแสดงรายการข้อมูลด้วย FlatList

บทนี้ได้แนะนำ `FlatList` ซึ่งเป็น Component สำคัญใน React Native สำหรับการแสดงรายการข้อมูลจำนวนมากอย่างมีประสิทธิภาพ โดยเน้นที่การใช้งาน `data` และ `renderItem`...

การแสดงรายการข้อมูลด้วย FlatList

สวัสดีครับเพื่อนๆ นักพัฒนา React Native ทุกท่าน! จากบทที่แล้วที่เราได้เรียนรู้เกี่ยวกับการสร้างปุ่มกดด้วย Button และ TouchableOpacity กันไปแล้ว ในบทนี้เราจะมาเรียนรู้วิธีการแสดงรายการข้อมูลจำนวนมากอย่างมีประสิทธิภาพด้วย FlatList ซึ่งเป็น Component ที่ขาดไม่ได้ในการสร้างแอปพลิเคชันที่มีข้อมูลเยอะๆ ครับ

ทำไมต้อง FlatList?

ลองนึกภาพว่าเราต้องการแสดงรายชื่อเพื่อน 100 คนในแอปของเรา หากเราใช้ View และ Text มาเรียงต่อกัน 100 อัน อาจจะทำให้แอปของเราหน่วงหรือกระตุกได้ เพราะการสร้าง Component จำนวนมากพร้อมกัน จะกินทรัพยากรเครื่องเยอะมาก FlatList ถูกออกแบบมาเพื่อแก้ปัญหานี้โดยเฉพาะ โดยจะทำการ Render เฉพาะ Component ที่มองเห็นบนหน้าจอเท่านั้น (Virtualization) ทำให้แอปของเราทำงานได้อย่างลื่นไหล แม้จะมีข้อมูลจำนวนมหาศาล

การใช้งาน FlatList เบื้องต้น

FlatList เป็น Component ที่รับ Props หลักๆ 2 ตัว คือ data และ renderItem

  • data: คือ Array ของข้อมูลที่เราต้องการแสดง
  • renderItem: คือ Function ที่รับข้อมูลแต่ละตัวใน data มา Render เป็น Component

มาดูตัวอย่างโค้ดกันเลยครับ

import React from 'react';
import { FlatList, StyleSheet, Text, View } from 'react-native';

const data = [
  { id: '1', name: 'John Doe' },
  { id: '2', name: 'Jane Smith' },
  { id: '3', name: 'Peter Jones' },
  { id: '4', name: 'Mary Brown' },
];

const Item = ({ name }) => (
  <View style={styles.item}>
    <Text style={styles.title}>{name}</Text>
  </View>
);

const App = () => {
  const renderItem = ({ item }) => (
    <Item name={item.name} />
  );

  return (
    <View style={styles.container}>
      <FlatList
        data={data}
        renderItem={renderItem}
        keyExtractor={item => item.id}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: 20,
  },
  item: {
    backgroundColor: '#f9c2ff',
    padding: 20,
    marginVertical: 8,
    marginHorizontal: 16,
  },
  title: {
    fontSize: 32,
  },
});

export default App;

คำอธิบายโค้ด:

  • เรา import FlatList, StyleSheet, Text และ View จาก react-native
  • สร้าง Array ชื่อ data เก็บข้อมูลชื่อและ ID ของคน
  • สร้าง Component ชื่อ Item เพื่อแสดงข้อมูลแต่ละคน โดยรับ name เป็น Prop
  • สร้าง Function ชื่อ renderItem ที่รับ item (ข้อมูลแต่ละตัวใน data) และส่ง item.name ให้กับ Component Item
  • ใน Component App เราใช้ FlatList โดยกำหนด data เป็น Array data ของเรา และ renderItem เป็น Function renderItem
  • keyExtractor คือ Prop ที่จำเป็นต้องกำหนด เพื่อให้ FlatList รู้ว่า Key ไหนคือ Unique Key ของแต่ละ Item ใน List เราใช้ item.id เพราะเรากำหนดให้เป็น Unique ID
  • เราสร้าง StyleSheet เพื่อตกแต่ง Component ให้สวยงาม

การปรับแต่ง FlatList

FlatList มี Props อีกมากมายที่เราสามารถใช้ปรับแต่งได้ เช่น

  • horizontal: กำหนดให้แสดงรายการในแนวนอน
  • numColumns: กำหนดจำนวน Column ในแนวตั้ง (ใช้ได้เฉพาะเมื่อไม่ได้กำหนด horizontal)
  • ListHeaderComponent: Component ที่จะแสดงเป็น Header ของ List
  • ListFooterComponent: Component ที่จะแสดงเป็น Footer ของ List
  • ItemSeparatorComponent: Component ที่จะแสดงคั่นระหว่างแต่ละ Item
  • onEndReached: Function ที่จะถูกเรียกเมื่อเลื่อนลงไปถึงท้าย List
  • onEndReachedThreshold: กำหนดระยะห่างจากท้าย List (เป็นสัดส่วน 0-1) ที่จะให้เรียก onEndReached
  • refreshing: กำหนดว่ากำลัง Refresh ข้อมูลอยู่หรือไม่
  • onRefresh: Function ที่จะถูกเรียกเมื่อทำการ Refresh ข้อมูล

มาดูตัวอย่างการใช้งาน Props เหล่านี้กันครับ

import React, { useState } from 'react';
import { FlatList, StyleSheet, Text, View, ActivityIndicator, RefreshControl } from 'react-native';

const data = [
  { id: '1', name: 'John Doe' },
  { id: '2', name: 'Jane Smith' },
  { id: '3', name: 'Peter Jones' },
  { id: '4', name: 'Mary Brown' },
  { id: '5', name: 'David Lee' },
  { id: '6', name: 'Sarah Wilson' },
  { id: '7', name: 'Michael Garcia' },
  { id: '8', name: 'Linda Rodriguez' },
  { id: '9', name: 'Christopher Williams' },
  { id: '10', name: 'Angela Davis' },
];

const Item = ({ name }) => (
  <View style={styles.item}>
    <Text style={styles.title}>{name}</Text>
  </View>
);

const App = () => {
  const [refreshing, setRefreshing] = useState(false);
  const [loadingMore, setLoadingMore] = useState(false);
  const [listData, setListData] = useState(data.slice(0,5)); // แสดงข้อมูลแค่ 5 รายการแรก

  const renderItem = ({ item }) => (
    <Item name={item.name} />
  );

  const onRefresh = () => {
    setRefreshing(true);
    // จำลองการดึงข้อมูลใหม่
    setTimeout(() => {
      setListData(data); // โหลดข้อมูลทั้งหมด
      setRefreshing(false);
    }, 2000);
  };

  const loadMoreData = () => {
    if (loadingMore) return; // ป้องกันการโหลดซ้ำ

    setLoadingMore(true);
    // จำลองการดึงข้อมูลเพิ่มเติม
    setTimeout(() => {
      const nextData = data.slice(listData.length, listData.length + 5);
      setListData([...listData, ...nextData]);
      setLoadingMore(false);
    }, 1000);
  };

  const renderFooter = () => {
    return (
      loadingMore ? (
        <View style={{ paddingVertical: 20 }}>
          <ActivityIndicator size="large" color="#0000ff" />
        </View>
      ) : null
    );
  };

  return (
    <View style={styles.container}>
      <FlatList
        data={listData}
        renderItem={renderItem}
        keyExtractor={item => item.id}
        refreshControl={
          <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
        }
        ListFooterComponent={renderFooter}
        onEndReached={loadMoreData}
        onEndReachedThreshold={0.5}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: 20,
  },
  item: {
    backgroundColor: '#f9c2ff',
    padding: 20,
    marginVertical: 8,
    marginHorizontal: 16,
  },
  title: {
    fontSize: 32,
  },
});

export default App;

คำอธิบายโค้ดเพิ่มเติม:

  • เราเพิ่ม useState Hook เพื่อจัดการ State ของ refreshing และ loadingMore
  • เราใช้ RefreshControl เพื่อเพิ่ม Pull-to-Refresh Functionality
  • onRefresh จะถูกเรียกเมื่อผู้ใช้ทำการ Pull-to-Refresh เราจำลองการดึงข้อมูลใหม่โดยใช้ setTimeout
  • เราใช้ ListFooterComponent เพื่อแสดง ActivityIndicator (ตัว Loading) เมื่อกำลังโหลดข้อมูลเพิ่มเติม
  • onEndReached จะถูกเรียกเมื่อเลื่อนลงไปใกล้ถึงท้าย List เราจำลองการดึงข้อมูลเพิ่มเติมโดยใช้ setTimeout
  • onEndReachedThreshold กำหนดไว้ที่ 0.5 หมายความว่า onEndReached จะถูกเรียกเมื่อเลื่อนลงไปถึงครึ่งทางของ Item สุดท้าย

ข้อผิดพลาดที่พบบ่อยและวิธีแก้ไข

  • Warning: Each child in a list should have a unique "key" prop.: เกิดจากการที่เราไม่ได้กำหนด keyExtractor หรือกำหนด Key ที่ไม่ Unique ให้กับแต่ละ Item ใน List วิธีแก้ไขคือ กำหนด keyExtractor ให้ถูกต้อง โดยใช้ Unique ID ของแต่ละ Item
  • Performance issues when rendering large lists: เกิดจากการที่เรา Render Component ที่ซับซ้อนมากเกินไปใน renderItem วิธีแก้ไขคือ พยายามทำให้ Component ที่ Render ใน renderItem มีขนาดเล็กและเรียบง่ายที่สุดเท่าที่จะทำได้ หรือใช้ React.memo เพื่อป้องกันการ Render Component ที่ไม่จำเป็น
  • FlatList not rendering: ตรวจสอบให้แน่ใจว่า data เป็น Array ที่ถูกต้อง และ renderItem ทำงานได้อย่างถูกต้อง นอกจากนี้ ตรวจสอบ Style ของ Container ว่ามี Height เพียงพอหรือไม่

สรุป

ในบทนี้เราได้เรียนรู้เกี่ยวกับการใช้งาน FlatList เพื่อแสดงรายการข้อมูลจำนวนมากอย่างมีประสิทธิภาพ เราได้เรียนรู้การกำหนด data และ renderItem และการปรับแต่ง FlatList ด้วย Props ต่างๆ หวังว่าเพื่อนๆ จะสามารถนำความรู้ที่ได้จากบทนี้ไปประยุกต์ใช้ในการสร้างแอปพลิเคชันของตัวเองได้นะครับ

ในบทต่อไป เราจะมาเรียนรู้เกี่ยวกับการ Navigation หรือการเปลี่ยนหน้าในแอปพลิเคชันกันครับ เตรียมตัวให้พร้อม แล้วเจอกันในบทหน้าครับ!

Office.in.th Custom Service

想基于此结构开发或定制系统?

Office.in.th 承接企业级 Web Application、API Integration 以及政府/企业管理系统的设计与开发,并提供长期支持。

查看软件开发服务