React.Component — คอมโพเนนต์แบบคลาสและวิธีการทำงาน

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-07-04 เวลาอ่าน: 9 นาที

React.Component เป็นคลาสพื้นฐานสำหรับการสร้างคอมโพเนนต์โดยใช้การสืบทอดใน React ก่อนที่จะมีการแนะนำฮุกในเวอร์ชัน 16.8 คอมโพเนนต์แบบคลาสเป็นวิธีเดียวในการจัดการสถานะและไลฟ์ไซเคิล ตามข้อมูลจาก React, 2024 คอมโพเนนต์แบบคลาสยังคงได้รับการสนับสนุน แม้ว่าคอมโพเนนต์แบบฟังก์ชันพร้อมฮุกจะถูกแนะนำสำหรับโปรเจกต์ใหม่

ประเด็นสำคัญ

  • React.Component เป็นคลาสพื้นฐานที่คอมโพเนนต์แบบคลาสสืบทอดผ่าน extends Component
  • สถานะ (State) ถูกจัดการผ่าน this.state และอัปเดตผ่าน this.setState เท่านั้น — การเปลี่ยนแปลงโดยตรงถูกห้าม
  • ไลฟ์ไซเคิล รวมถึงเมธอด componentDidMount, componentDidUpdate และ componentWillUnmount
  • this ในเมธอดของคลาสต้องการการผูกบริบท — ผ่าน bind, arrow function หรือ class fields
  • การย้าย ไปยังคอมโพเนนต์แบบฟังก์ชันสามารถทำได้ทีละน้อย: ฮุกและคลาสสามารถอยู่ร่วมกันในโปรเจกต์เดียวกัน

React.Component คืออะไร?

React.Component เป็นคลาสนามธรรมที่ให้เมธอดในตัวสำหรับการทำงานกับสถานะ พร็อพ และไลฟ์ไซเคิลของคอมโพเนนต์ ในการสร้างคอมโพเนนต์แบบคลาส คุณต้องกำหนดคลาสที่ขยาย React.Component และนำเมธอด render ไปใช้งาน

React.Component ปรากฏใน React เวอร์ชันแรกสุด (2013) และยังคงเป็น วิธีหลัก ในการสร้างคอมโพเนนต์เป็นเวลาห้าปี ระบบนิเวศของ React ถูกสร้างขึ้นรอบคลาส: คอมโพเนนต์ลำดับสูง (HOC), render props, บริบท — รูปแบบทั้งหมดนี้ถูกนำไปใช้งานโดยใช้ไวยากรณ์คลาส

ด้วยการเปิดตัว React 16.8 ในปี 2019 ทีม React ได้แนะนำ ฮุก เป็นทางเลือกแทนคลาส ฮุกแก้ปัญหาเดียวกัน — สถานะ เอฟเฟกต์ บริบท — แต่ไม่ต้องใช้การสืบทอดและการผูกบริบทที่ซับซ้อน React.Component ยังคงได้รับการสนับสนุนอย่างเต็มที่ แต่วิธีการแบบฟังก์ชันถูกแนะนำสำหรับโปรเจกต์ใหม่

การสร้างคอมโพเนนต์แบบคลาส

คอมโพเนนต์แบบคลาสขั้นต่ำคือคลาสที่มีเมธอด render เพียงตัวเดียวที่ส่งคืน React-element render เป็นเมธอดบังคับเพียงตัวเดียว มันต้องเป็นฟังก์ชันบริสุทธิ์ของ this.props และ this.state: ชุดพร็อพและสถานะเดียวกันให้ผลลัพธ์เดียวกัน

js
import React, { Component } from 'react';

class Welcome extends Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

คอนสตรัคเตอร์และการเริ่มต้นสถานะ

คอนสตรัคเตอร์ทำงานก่อนการเมานต์ มันเรียก super(props) เพื่อส่งพร็อพไปยังคลาสแม่และเริ่มต้น this.state การใช้คอนสตรัคเตอร์เพื่อวัตถุประสงค์อื่น — การสมัครสมาชิก, การเรียก API — ไม่แนะนำ; componentDidMount มีไว้สำหรับสิ่งนั้น

js
class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  render() {
    return <p>Count: {this.state.count}</p>;
  }
}

การจัดการสถานะด้วย this.state และ this.setState

this.state เป็นออบเจกต์ที่เก็บข้อมูลของคอมโพเนนต์ การเปลี่ยนแปลงโดยตรง (this.state.count = 1) ถูกห้าม — มันไม่ก่อให้เกิดการเรนเดอร์ใหม่และทำลายการคาดเดาได้ ต้องอัปเดตสถานะผ่าน this.setState ซึ่งสร้างออบเจกต์สถานะใหม่และก่อให้เกิดการเรนเดอร์ใหม่

setState สามารถรับออบเจกต์หรือฟังก์ชัน รูปแบบฟังก์ชันถูกเลือกเมื่อสถานะใหม่ขึ้นอยู่กับสถานะก่อนหน้า: this.setState(prev => ({ count: prev.count + 1 })) React สามารถรวมคำเรียก setState หลายครั้งเป็นชุดเดียวเพื่อเพิ่มประสิทธิภาพ

js
class Toggle extends Component {
  constructor(props) {
    super(props);
    this.state = { isOn: false };
  }

  handleClick() {
    this.setState(prev => ({ isOn: !prev.isOn }));
  }

  render() {
    return (
      <button onClick={() => this.handleClick()}>
        {this.state.isOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

คุณสมบัติที่สำคัญของ setState คือมันเป็น อะซิงโครนัส หลังจากเรียก setState สถานะจะไม่อัปเดตทันที หากคุณต้องการดำเนินการหลังจากการอัปเดต ให้ส่งคอลแบ็กเป็นอาร์กิวเมนต์ที่สอง: this.setState(newState, () => console.log(this.state))

เมธอดไลฟ์ไซเคิล

คอมโพเนนต์แบบคลาสมีเมธอดที่กำหนดไว้ล่วงหน้าที่ React เรียกในช่วงเวลาที่กำหนด การเมานต์ — constructor → render → componentDidMount การอัปเดต — render → componentDidUpdate การเลิกเมานต์ — componentWillUnmount

เมธอดระยะวัตถุประสงค์
constructorการเมานต์เริ่มต้นสถานะและผูกเมธอด
renderทุกครั้งส่งคืน React-element (บังคับ)
componentDidMountหลังเมานต์คำขอ API, การสมัครสมาชิก, ตัวจับเวลา
componentDidUpdateหลังอัปเดตตอบสนองต่อการเปลี่ยนแปลงพร็อพ/สถานะ
componentWillUnmountก่อนลบทำความสะอาดการสมัครสมาชิก ตัวจับเวลา ตัวฟังเหตุการณ์

ComponentDidMount — การดึงข้อมูล

componentDidMount เป็นสถานที่หลักสำหรับ เอฟเฟกต์ข้างเคียง หลังจากการเรนเดอร์ครั้งแรก ที่นี่คุณดำเนินการคำขอ HTTP, สร้างการเชื่อมต่อ WebSocket และเริ่มตัวจับเวลา หากคุณไม่ทำความสะอาดการสมัครสมาชิกใน componentWillUnmount จะเกิดการรั่วไหลของหน่วยความจำ

js
class UserProfile extends Component {
  componentDidMount() {
    fetch(`/api/users/${this.props.userId}`)
      .then(res => res.json())
      .then(data => this.setState({ user: data }));
  }

  componentWillUnmount() {
    // Cancel request on unmount
  }

  render() {
    return <div>{this.state.user?.name}</div>;
  }
}

การผูกบริบท this ในเมธอด

ใน JavaScript เมธอดของคลาสไม่ได้ผูกกับอินสแตนซ์โดยค่าเริ่มต้น หากคุณส่งเมธอดเป็นคอลแบ็ก — ไปยังตัวจัดการเหตุการณ์, ไปยังตัวจับเวลา — this จะเป็น undefined (ในโหมดเข้มงวด) หรือ window (ไม่มีโหมดเข้มงวด) หากไม่ผูก this.setState จะโยนข้อผิดพลาด

มีสามวิธีในการผูก: bind ในคอนสตรัคเตอร์, arrow function ในคอลแบ็ก และ class field กับ arrow function วิธีแรกเป็นคำแนะนำอย่างเป็นทางการของ React: ผูกครั้งเดียวในคอนสตรัคเตอร์ โดยไม่สร้างฟังก์ชันใหม่ทุกครั้งที่เรนเดอร์

js
// Method 1: bind in constructor (recommended)
class MyComponent extends Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState({ clicked: true });
  }

  render() {
    return <button onClick={this.handleClick}>Click</button>;
  }
}

Class fields — ไวยากรณ์สมัยใหม่พร้อมการผูกอัตโนมัติ Arrow function ในคุณสมบัติของคลาสจะจับ this จากขอบเขตของคอนสตรัคเตอร์ ข้อเสียคือเมธอดถูกสร้างขึ้นในแต่ละอินสแตนซ์ ไม่ใช่บนต้นแบบ ซึ่งเพิ่มการใช้หน่วยความจำสำหรับคอมโพเนนต์หลายร้อยตัวชนิดเดียวกัน

คอมโพเนนต์แบบคลาส vs แบบฟังก์ชัน

การเลือกระหว่างคลาสและฟังก์ชันไม่ใช่แค่เรื่องของไวยากรณ์ คอมโพเนนต์แบบฟังก์ชัน พร้อมฮุกแก้ปัญหาที่มีอยู่ในคลาส: การทำซ้ำตรรกะในเมธอดไลฟ์ไซเคิลที่แตกต่างกัน (componentDidMount + componentDidUpdate), ความซับซ้อนกับ this และไม่สามารถแยกตรรกะที่เกี่ยวข้องออกเป็นบล็อกที่นำกลับมาใช้ใหม่ได้

คอมโพเนนต์แบบฟังก์ชัน ทดสอบง่ายกว่า — ไม่มีสถานะภายใน (ซึ่งก่อนฮุกมีเฉพาะในคลาส) และไม่ต้องการการเมานต์ใน DOM เพื่อตรวจสอบคอลแบ็ก React แนะนำคอมโพเนนต์แบบฟังก์ชันสำหรับโปรเจกต์ใหม่ทั้งหมด; เอกสารและตัวอย่างถูกเขียนด้วยคอมโพเนนต์เหล่านี้

คอมโพเนนต์แบบคลาสยังคงเป็นตัวเลือกที่ดีที่สุดเมื่อทำงานกับ โค้ดเก่า หากโปรเจกต์เริ่มก่อนปี 2019 โปรเจกต์นั้นอาจมีคอมโพเนนต์แบบคลาสนับพัน การเขียนใหม่ทั้งหมดเป็นฮุกในสปรินต์เดียวมีความเสี่ยง React รับประกันความเข้ากันได้ย้อนหลัง: คอมโพเนนต์แบบคลาสจะไม่ถูกลบ

กลยุทธ์การย้ายจากคลาสไปยังฮุก

การย้ายทีละน้อยเริ่มต้นด้วยการวิเคราะห์คอมโพเนนต์ คอมโพเนนต์ง่าย ๆ ที่ไม่มีสถานะ ถูกแปลงก่อน — มันถูกแทนที่ด้วยฟังก์ชันได้อย่างง่ายดาย จากนั้น — คอมโพเนนต์ที่มีฟิลด์สถานะหนึ่งหรือสองฟิลด์ ซึ่ง useState แทนที่ this.state และ this.setState โดยตรง

คอมโพเนนต์ที่ซับซ้อนที่มีหลายเมธอดไลฟ์ไซเคิลถูกแปลงผ่าน useEffect ตรรกะจาก componentDidMount + componentDidUpdate ถูกแบ่งออกเป็นคำเรียก useEffect แยกต่างหากพร้อมการพึ่งพาที่แตกต่างกัน componentWillUnmount ถูกแทนที่ด้วยฟังก์ชันส่งคืนภายใน useEffect สำหรับตรรกะสถานะที่ซับซ้อน ให้ใช้ useReducer

เครื่องมือการย้ายอัตโนมัติ — @phenomnomnominal/ts-react-class-to-hook หรือสคริปต์ codemod — สามารถแปลงคลาสอย่างง่ายได้โดยอัตโนมัติ สำหรับกรณีที่ซับซ้อน การย้ายยังคงเป็นงานที่ต้องทำด้วยตนเองซึ่งต้องเข้าใจตรรกะของคอมโพเนนต์ต้นทาง

คำถามที่พบบ่อย

จำเป็นต้องเรียก super(props) ในคอนสตรัคเตอร์หรือไม่?

ใช่ super(props) ส่งพร็อพไปยัง React.Component แม่ หากไม่มีการเรียกนี้ this.props จะเป็น undefined ภายในคอนสตรัคเตอร์ ใน render และเมธอดไลฟ์ไซเคิล พร็อพสามารถใช้ได้แม้ไม่มี super แต่เป็นพฤติกรรมพลอยได้ของการนำไปใช้งาน

ทำไม setState ถึงเป็นอะซิงโครนัส?

React รวมคำเรียก setState หลายครั้งเป็นชุดเดียวเพื่อลดการเรนเดอร์ใหม่ที่ไม่จำเป็น หาก setState เป็นซิงโครนัส แต่ละคำเรียกจะก่อให้เกิดการเรนเดอร์ทันที ทำให้ประสิทธิภาพลดลงระหว่างการอัปเดตจำนวนมาก

ฉันสามารถใช้ฮุกภายในคอมโพเนนต์แบบคลาสได้หรือไม่?

ไม่ได้ ฮุก ทำงานเฉพาะในคอมโพเนนต์แบบฟังก์ชัน สำหรับโปรเจกต์ที่มีคอมโพเนนต์แบบคลาส รูปแบบเก่าทั้งหมดยังคงใช้ได้: render props, HOC และ Consumer สำหรับบริบท การย้ายไปยังฮุกต้องแปลงคลาสเป็นฟังก์ชัน

PureComponent คืออะไรและแตกต่างจาก Component อย่างไร?

React.PureComponent นำ shouldComponentUpdate ไปใช้ด้วยการเปรียบเทียบพร็อพและสถานะแบบผิวเผิน ต่างจาก Component ที่เรนเดอร์ใหม่เสมอเมื่อ setState PureComponent ข้ามการเรนเดอร์ใหม่หากข้อมูลไม่เปลี่ยนแปลง นี่เป็นการเพิ่มประสิทธิภาพสำหรับคอมโพเนนต์ที่ไม่มีการซ้อนซับซ้อน

ฉันจะจัดการข้อผิดพลาดในคอมโพเนนต์แบบคลาสได้อย่างไร?

ใช้ componentDidCatch และ getDerivedStateFromError componentDidCatch(error, info) บันทึกข้อผิดพลาด getDerivedStateFromError อัปเดตสถานะเพื่อแสดง UI สำรอง เมธอดเหล่านี้ทำงานเฉพาะในคอมโพเนนต์แบบคลาส — ฟังก์ชันต้องมีคอมโพเนนต์ ErrorBoundary ที่ครอบอยู่

สรุป

  • React.Component เป็นคลาสพื้นฐานสำหรับคอมโพเนนต์ที่มีการสืบทอด สถานะ และเมธอดไลฟ์ไซเคิล
  • this.state เริ่มต้นในคอนสตรัคเตอร์ อัปเดตผ่าน this.setState เท่านั้น — การเปลี่ยนแปลงโดยตรงถูกห้าม
  • componentDidMount เป็นสถานที่หลักสำหรับคำขอ API การสมัครสมาชิก และตัวจับเวลาหลังการเรนเดอร์ครั้งแรก
  • componentWillUnmount คือการทำความสะอาดที่จำเป็นของการสมัครสมาชิกและตัวจับเวลาเพื่อป้องกันการรั่วไหลของหน่วยความจำ
  • การผูก this จำเป็น: bind ในคอนสตรัคเตอร์เป็นวิธีที่แนะนำสำหรับเมธอดคอลแบ็ก
  • ฮุก ได้แทนที่คอมโพเนนต์แบบคลาสสำหรับโปรเจกต์ใหม่ แต่คลาสยังคงได้รับการสนับสนุนอย่างเต็มที่
  • การย้าย ไปยังฮุกทำทีละน้อย: คอมโพเนนต์ไร้สถานะก่อน ส่วนที่ซับซ้อนผ่าน useReducer และ useEffect

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม