跳到主要内容

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

系统指南 内容已审核

Fetching Data จาก API ด้วย useEffect และ useState

บทนี้เป็นการแนะนำวิธีการดึงข้อมูลจาก API ใน React Native โดยใช้ `useEffect` Hook เพื่อจัดการ Side Effects เช่น การ Fetch Data และ `useState` Hook เพื่อเก็บข้อมู...

Fetching Data จาก API ด้วย useEffect และ useState

สวัสดีครับ! ในบทที่ 12 เราได้เรียนรู้เกี่ยวกับการบันทึกข้อมูลแบบ Local ด้วย AsyncStorage ไปแล้ว ในบทนี้ เราจะมาเรียนรู้วิธีการดึงข้อมูลจากภายนอกแอปพลิเคชันของเรา หรือที่เรียกกันว่าการ Fetching Data จาก API (Application Programming Interface) โดยเราจะใช้ Hook สองตัวที่สำคัญมากใน React Native นั่นคือ useEffect และ useState

การดึงข้อมูลจาก API เป็นสิ่งจำเป็นสำหรับแอปพลิเคชันส่วนใหญ่ เพราะเรามักจะต้องแสดงข้อมูลที่เปลี่ยนแปลงอยู่เสมอ เช่น ข่าวสาร, ราคาสินค้า, หรือข้อมูลผู้ใช้งาน ซึ่งข้อมูลเหล่านี้มักจะเก็บอยู่ใน Server ที่เราต้องทำการร้องขอ (Request) เพื่อนำมาแสดงผลในแอปของเรา

ทำความเข้าใจกับ useEffect Hook

useEffect Hook เป็น Hook ที่ใช้จัดการ Side Effects ใน React Native Side Effects คืออะไร? มันคือการทำงานบางอย่างที่เกิดขึ้น "ข้างนอก" Component ของเรา เช่น การดึงข้อมูลจาก API, การตั้ง Timer, หรือการ Subscribe Event Listener

โครงสร้างพื้นฐานของ useEffect Hook เป็นดังนี้:

import React, { useEffect } from 'react';

function MyComponent() {
  useEffect(() => {
    // โค้ดที่จะทำงานเมื่อ Component ถูก Mount (แสดงผลครั้งแรก)
    // และอาจจะทำงานอีกครั้งเมื่อ Dependencies เปลี่ยนแปลง

    return () => {
      // โค้ดที่จะทำงานเมื่อ Component ถูก Unmount (ถูกถอดออกจากหน้าจอ)
      // หรือเมื่อ Dependencies เปลี่ยนแปลงก่อนที่ Effect จะทำงานอีกครั้ง
    };
  }, [/* Dependencies */]);

  return (
    // UI ของ Component
  );
}
  • Callback Function: ฟังก์ชันแรกที่ส่งเข้าไปใน useEffect คือฟังก์ชันที่จะทำงานเมื่อ Component ถูก Mount หรือเมื่อ Dependencies เปลี่ยนแปลง
  • Dependencies Array: อาร์เรย์ที่ระบุว่า Effect นี้จะทำงานใหม่เมื่อค่าของตัวแปรใดในอาร์เรย์นี้เปลี่ยนแปลง ถ้าเป็นอาร์เรย์ว่าง [] หมายความว่า Effect จะทำงานเพียงครั้งเดียวตอน Mount เท่านั้น ถ้าไม่ระบุอาร์เรย์เลย Effect จะทำงานใหม่ทุกครั้งที่ Component Render
  • Cleanup Function (Optional): ฟังก์ชันที่ return ออกมาจาก Callback Function จะถูกเรียกเมื่อ Component ถูก Unmount หรือเมื่อ Dependencies เปลี่ยนแปลงก่อนที่ Effect จะทำงานอีกครั้ง ฟังก์ชันนี้มักใช้ในการยกเลิก Side Effects เช่น การยกเลิก Subscription หรือการลบ Timer

กรณีใช้งานจริง: การดึงข้อมูลจาก API เมื่อ Component ถูก Mount

import React, { useState, useEffect } from 'react';
import { View, Text } from 'react-native';

function MyComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    async function fetchData() {
      const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
      const json = await response.json();
      setData(json);
    }

    fetchData();
  }, []);

  if (data === null) {
    return <Text>Loading...</Text>;
  }

  return (
    <View>
      <Text>Title: {data.title}</Text>
      <Text>Completed: {data.completed ? 'Yes' : 'No'}</Text>
    </View>
  );
}

export default MyComponent;

คำอธิบาย:

  • เราใช้ useState Hook เพื่อสร้าง State ที่ชื่อว่า data ซึ่งจะเก็บข้อมูลที่ได้จาก API
  • เราใช้ useEffect Hook โดยมี Dependencies เป็นอาร์เรย์ว่าง [] ซึ่งหมายความว่า Effect จะทำงานเพียงครั้งเดียวตอน Mount เท่านั้น
  • ใน useEffect เราสร้างฟังก์ชัน fetchData ที่ใช้ fetch API เพื่อดึงข้อมูลจาก API
  • เราใช้ async/await เพื่อให้โค้ดอ่านง่ายขึ้น และรอให้การดึงข้อมูลเสร็จสิ้นก่อนที่จะนำข้อมูลมา Update State
  • เมื่อข้อมูลถูกดึงมาได้แล้ว เราจะ Update State data ด้วยข้อมูลที่ได้
  • ก่อนที่ข้อมูลจะถูกดึงมา เราจะแสดงข้อความ "Loading..." เพื่อบอกให้ผู้ใช้ทราบว่ากำลังมีการดึงข้อมูล
  • เมื่อข้อมูลถูกดึงมาได้แล้ว เราจะแสดงผลข้อมูลใน Component

การใช้ fetch API

fetch API เป็น API ที่มีอยู่ใน JavaScript สำหรับใช้ในการส่ง HTTP Request ไปยัง Server และรับ Response กลับมา

โครงสร้างพื้นฐานของ fetch API เป็นดังนี้:

fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => {
    // ทำงานกับข้อมูลที่ได้
  })
  .catch(error => {
    // จัดการข้อผิดพลาด
  });

คำอธิบาย:

  • fetch('https://api.example.com/data') ส่ง GET Request ไปยัง URL ที่ระบุ
  • .then(response => response.json()) แปลง Response ที่ได้ให้อยู่ในรูปแบบ JSON
  • .then(data => { ... }) ทำงานกับข้อมูลที่ได้จาก API
  • .catch(error => { ... }) จัดการข้อผิดพลาดที่อาจเกิดขึ้นระหว่างการ Fetch Data

ข้อดีของการใช้ Async/Await: ทำให้โค้ดอ่านง่ายและจัดการได้ง่ายกว่า Promise Chains

async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    // ทำงานกับข้อมูลที่ได้
  } catch (error) {
    // จัดการข้อผิดพลาด
  }
}

การจัดการ Loading State และ Error Handling

เมื่อเราดึงข้อมูลจาก API สิ่งสำคัญคือต้องจัดการ Loading State และ Error Handling เพื่อให้ผู้ใช้ได้รับประสบการณ์ที่ดี

Loading State: แสดงสถานะ Loading ในขณะที่กำลังดึงข้อมูล

import React, { useState, useEffect } from 'react';
import { View, Text, ActivityIndicator } from 'react-native';

function MyComponent() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true); // เพิ่ม Loading State

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
        const json = await response.json();
        setData(json);
      } catch (error) {
        console.error(error);
      } finally {
        setLoading(false); // ปิด Loading State ไม่ว่าจะสำเร็จหรือไม่ก็ตาม
      }
    }

    fetchData();
  }, []);

  if (loading) {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <ActivityIndicator size="large" color="#0000ff" />
        <Text>Loading...</Text>
      </View>
    );
  }

  return (
    <View>
      <Text>Title: {data.title}</Text>
      <Text>Completed: {data.completed ? 'Yes' : 'No'}</Text>
    </View>
  );
}

export default MyComponent;

Error Handling: จัดการข้อผิดพลาดที่อาจเกิดขึ้นระหว่างการ Fetch Data

import React, { useState, useEffect } from 'react';
import { View, Text } from 'react-native';

function MyComponent() {
  const [data, setData] = useState(null);
  const [error, setError] = useState(null); // เพิ่ม Error State

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await fetch('https://jsonplaceholder.typicode.com/todos/invalid-endpoint'); // Endpoint ที่ไม่ถูกต้อง
        const json = await response.json();
        setData(json);
      } catch (error) {
        console.error(error);
        setError(error); // Update Error State
      }
    }

    fetchData();
  }, []);

  if (error) {
    return <Text>Error: {error.message}</Text>;
  }

  if (data === null) {
    return <Text>Loading...</Text>;
  }

  return (
    <View>
      <Text>Title: {data.title}</Text>
      <Text>Completed: {data.completed ? 'Yes' : 'No'}</Text>
    </View>
  );
}

export default MyComponent;

ข้อผิดพลาดที่พบบ่อย:

  • CORS Error: เกิดขึ้นเมื่อ Server ไม่อนุญาตให้ Client ที่มาจาก Domain อื่นเข้าถึงข้อมูล (Cross-Origin Resource Sharing) วิธีแก้ไขคือให้ Server กำหนด Header Access-Control-Allow-Origin ให้ถูกต้อง หรือใช้ Proxy Server
  • Network Error: เกิดขึ้นเมื่อไม่มีการเชื่อมต่ออินเทอร์เน็ต หรือ Server ไม่สามารถเข้าถึงได้
  • JSON Parsing Error: เกิดขึ้นเมื่อ Response ที่ได้จาก Server ไม่ใช่ JSON ที่ถูกต้อง

Performance Considerations:

  • Caching: พิจารณาใช้ Caching เพื่อลดจำนวน Request ที่ส่งไปยัง Server โดยเฉพาะข้อมูลที่ไม่ค่อยมีการเปลี่ยนแปลง
  • Debouncing/Throttling: ใช้ Debouncing หรือ Throttling เพื่อควบคุมความถี่ในการส่ง Request เมื่อมีการเปลี่ยนแปลง State บ่อยๆ เช่น ใน TextInput

Security Considerations:

  • HTTPS: ใช้ HTTPS เสมอเพื่อเข้ารหัสข้อมูลที่ส่งระหว่าง Client และ Server
  • API Keys: เก็บ API Keys ไว้ใน Environment Variables และไม่ Commit ลงใน Source Code

สรุป: ในบทนี้เราได้เรียนรู้วิธีการดึงข้อมูลจาก API ด้วย useEffect และ useState Hook รวมถึงการจัดการ Loading State และ Error Handling หวังว่าความรู้เหล่านี้จะเป็นประโยชน์ในการพัฒนาแอปพลิเคชัน React Native ของคุณนะครับ ในบทถัดไป เราจะมาเรียนรู้เกี่ยวกับการใช้งาน Activity Indicator เพื่อแสดงสถานะ Loading ให้สวยงามยิ่งขึ้น

Office.in.th Custom Service

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

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

查看软件开发服务