跳到主要内容

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

系统指南 内容已审核

State คืออะไร? การจัดการ State ใน Component

บทความนี้อธิบายถึง State ใน React Native ซึ่งเป็นข้อมูลภายใน Component ที่สามารถเปลี่ยนแปลงได้ และการเปลี่ยนแปลงนี้จะทำให้ Component ทำการ Re-rendering เพื่ออัพ...

State คืออะไร? การจัดการ State ใน Component

สวัสดีครับเพื่อนๆ นักพัฒนา React Native ทุกท่าน! ในบทความที่แล้ว เราได้ทำความเข้าใจเกี่ยวกับ Props ซึ่งเป็นข้อมูลที่ส่งจาก Component หนึ่งไปยังอีก Component หนึ่ง คล้ายกับการส่งของขวัญจากพ่อแม่ให้ลูก แต่ในบทความนี้ เราจะมาพูดถึง State ซึ่งเป็นข้อมูลที่ Component แต่ละตัว "เป็นเจ้าของ" และจัดการเอง คล้ายกับของเล่นที่ลูกมีและสามารถเล่นกับมันได้ตามใจชอบ ถ้าพร้อมแล้ว เราไปดูกันเลย!

State คืออะไร?

State ใน React Native (และ React) คือข้อมูลภายใน Component ที่สามารถเปลี่ยนแปลงได้ เมื่อ State เปลี่ยนแปลง Component จะทำการ Re-rendering หรือวาดใหม่ เพื่อแสดงผลลัพธ์ที่อัพเดตตาม State ที่เปลี่ยนไป ลองนึกภาพว่าคุณมี Component ที่แสดงจำนวนครั้งที่กดปุ่ม ทุกครั้งที่คุณกดปุ่ม จำนวนครั้งที่แสดงบนหน้าจอจะเพิ่มขึ้น ข้อมูลจำนวนครั้งนี้แหละครับ คือ State

State ต่างจาก Props ตรงที่ Props เป็นข้อมูลที่มาจากภายนอก (Parent Component) และอ่านได้อย่างเดียว (read-only) ส่วน State เป็นข้อมูลภายใน Component ที่สามารถเปลี่ยนแปลงได้ และการเปลี่ยนแปลง State จะทำให้ Component อัพเดตตัวเอง

การใช้ useState Hook

ใน React Native (และ React ตั้งแต่เวอร์ชัน 16.8 เป็นต้นไป) เราใช้สิ่งที่เรียกว่า Hook เพื่อจัดการ State Hook เป็นฟังก์ชันพิเศษที่ช่วยให้เรา "Hook" เข้าไปในฟีเจอร์ของ React โดยไม่ต้องเขียน Class Component หนึ่งใน Hook ที่สำคัญที่สุดคือ useState

useState Hook ช่วยให้เราเพิ่ม State ลงใน Functional Component ได้ วิธีการใช้งานง่ายมากครับ

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

const MyComponent = () => {
  // ประกาศ State โดยใช้ useState Hook
  const [count, setCount] = useState(0);

  return (
    <View>
      <Text>You clicked {count} times</Text>
      <Button
        title="Click me"
        onPress={() => setCount(count + 1)}
      />
    </View>
  );
};

export default MyComponent;

มาดูกันทีละส่วนครับ

  • import React, { useState } from 'react';: บรรทัดนี้เรา import React และ useState Hook เข้ามาใน Component
  • const [count, setCount] = useState(0);: ตรงนี้คือหัวใจสำคัญ เราเรียก useState(0) ซึ่งหมายความว่าเราสร้าง State ชื่อ count โดยมีค่าเริ่มต้นเป็น 0 useState จะคืนค่ากลับมาเป็น Array ที่มีสมาชิก 2 ตัว:
    • count: ตัวแปรที่เก็บค่า State ปัจจุบัน
    • setCount: ฟังก์ชันที่เราใช้เพื่ออัพเดตค่า State
  • <Text>You clicked {count} times</Text>: เราแสดงค่า State count ใน Text Component
  • <Button title="Click me" onPress={() => setCount(count + 1)} />: เมื่อกดปุ่ม "Click me" ฟังก์ชัน setCount(count + 1) จะถูกเรียก ซึ่งจะอัพเดตค่า State count โดยเพิ่มค่าขึ้นทีละ 1

สังเกตว่าเมื่อเราเรียก setCount(count + 1) Component MyComponent จะทำการ Re-rendering ทำให้ค่า count ที่แสดงบนหน้าจออัพเดตตามไปด้วย

การเปลี่ยนแปลง State และ Re-rendering

เมื่อ State เปลี่ยนแปลง React Native จะทำการ Re-rendering Component นั้นๆ เพื่อให้ UI อัพเดตตาม State ใหม่ กระบวนการนี้เกิดขึ้นโดยอัตโนมัติเมื่อเราเรียกฟังก์ชันที่ได้จากการเรียก useState (เช่น setCount ในตัวอย่างก่อนหน้า)

**ข้อควรจำ:** ห้ามเปลี่ยนแปลง State โดยตรง! เช่น count = count + 1; เพราะ React Native จะไม่สามารถตรวจจับการเปลี่ยนแปลงนี้ได้ และ Component จะไม่ Re-render เสมอไป เราต้องใช้ฟังก์ชันที่ได้จาก useState เสมอ (เช่น setCount) เพื่อให้ React Native รู้ว่า State มีการเปลี่ยนแปลง

ลองดูตัวอย่างที่ไม่ถูกต้อง:

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

const MyComponent = () => {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    // ผิด! ห้ามทำแบบนี้
    count = count + 1;
    console.log(count); // ค่า count จะเปลี่ยนใน console แต่ UI ไม่เปลี่ยน
  };

  return (
    <View>
      <Text>You clicked {count} times</Text>
      <Button
        title="Click me"
        onPress={handleClick}
      />
    </View>
  );
};

export default MyComponent;

ในตัวอย่างนี้ แม้ว่าค่า count จะเปลี่ยนใน console.log แต่ UI จะไม่เปลี่ยนแปลง เพราะเราไม่ได้ใช้ setCount เพื่ออัพเดต State

State ที่ซับซ้อน: Objects และ Arrays

State ไม่ได้จำกัดอยู่แค่ตัวเลขหรือข้อความ เราสามารถใช้ State เก็บ Objects และ Arrays ได้เช่นกัน

**การจัดการ State ที่เป็น Object:**

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

const MyComponent = () => {
  const [person, setPerson] = useState({
    name: 'John Doe',
    age: 30,
  });

  const updateName = () => {
    // สำคัญ: ต้องสร้าง Object ใหม่ทุกครั้ง
    setPerson({
      ...person, // คัดลอก Properties เดิม
      name: 'Jane Doe', // เปลี่ยนเฉพาะ name
    });
  };

  return (
    <View>
      <Text>Name: {person.name}</Text>
      <Text>Age: {person.age}</Text>
      <Button
        title="Update Name"
        onPress={updateName}
      />
    </View>
  );
};

export default MyComponent;

เมื่อเราต้องการอัพเดต State ที่เป็น Object สิ่งสำคัญคือต้องสร้าง Object ใหม่ทุกครั้ง โดยใช้ Spread Operator (...) เพื่อคัดลอก Properties เดิมของ Object แล้วค่อยแก้ไข Property ที่เราต้องการเปลี่ยนแปลง การทำแบบนี้จะทำให้ React Native รู้ว่า Object มีการเปลี่ยนแปลงจริงๆ

**การจัดการ State ที่เป็น Array:**

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

const MyComponent = () => {
  const [items, setItems] = useState(['Apple', 'Banana', 'Orange']);

  const addItem = () => {
    // สำคัญ: ต้องสร้าง Array ใหม่ทุกครั้ง
    setItems([...items, 'Grapes']);
  };

  return (
    <View>
      <FlatList
        data={items}
        renderItem={({ item }) => <Text>{item}</Text>}
        keyExtractor={(item) => item}
      />
      <Button
        title="Add Item"
        onPress={addItem}
      />
    </View>
  );
};

export default MyComponent;

เช่นเดียวกับการจัดการ Object เมื่อเราต้องการอัพเดต State ที่เป็น Array เราต้องสร้าง Array ใหม่ทุกครั้ง โดยใช้ Spread Operator (...) เพื่อคัดลอก Elements เดิมของ Array แล้วค่อยเพิ่มหรือแก้ไข Elements ที่เราต้องการเปลี่ยนแปลง

Performance Considerations

การเปลี่ยนแปลง State บ่อยๆ อาจส่งผลต่อ Performance ของแอปได้ โดยเฉพาะอย่างยิ่งถ้า Component มีขนาดใหญ่และซับซ้อน ดังนั้นเราควรพิจารณาถึง Performance เมื่อจัดการ State

  • Memoization: ใช้ useMemo และ useCallback Hooks เพื่อป้องกันการ Re-render Component ที่ไม่จำเป็น
  • Immutable Data Structures: ใช้ Immutable Data Structures (เช่น Immutable.js) เพื่อให้การตรวจจับการเปลี่ยนแปลง State เป็นไปอย่างมีประสิทธิภาพ

สรุป

State เป็นแนวคิดที่สำคัญมากในการพัฒนา React Native ช่วยให้เราสร้าง Component ที่มีการเปลี่ยนแปลงและตอบสนองต่อการกระทำของผู้ใช้ได้ การใช้ useState Hook ทำให้การจัดการ State ใน Functional Component เป็นเรื่องง่าย แต่ก็ต้องระมัดระวังในการอัพเดต State โดยเฉพาะอย่างยิ่ง State ที่เป็น Object หรือ Array เพื่อให้แน่ใจว่า React Native สามารถตรวจจับการเปลี่ยนแปลงได้อย่างถูกต้องและมีประสิทธิภาพ

ในบทความถัดไป เราจะมาเรียนรู้เกี่ยวกับการใช้ StyleSheet เพื่อตกแต่ง Component ให้สวยงาม น่าใช้งานมากยิ่งขึ้น แล้วพบกันใหม่ครับ!

Office.in.th Custom Service

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

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

查看软件开发服务