เริ่มต้นใช้งาน React Javascript Library

เผยแพร่แล้ว: 2022-02-16

หากคุณใช้เวลาในโลกของ WordPress คุณอาจเจอ Zac Gordon Zac เป็นครูที่กระตือรือร้นและมีเสน่ห์ที่เน้น Javascript ใน WordPress เขายืมวลี "Learn Javascript Deeply" จาก Matt Mullenweg และทำเป็นสโลแกนส่วนตัวของเขา

ในช่วงหลายปีที่ผ่านมา Zac ได้ผลิตวิดีโอคลาส การประชุมออนไลน์ การพูดคุยสด และพอดแคสต์ที่เน้นการสอนวิธีใช้ Javascript ใน WordPress

ฉันดีใจที่จะบอกว่าเรากำลังทำงานร่วมกับ Zac ในหนังสือ "React Explained" React คือไลบรารี่ที่ทีม WordPress เลือกใช้สำหรับตัวแก้ไข Gutenberg ใหม่ พวกเขาไม่ได้อยู่คนเดียว - ทั้ง Drupal และ Magento ต่างก็เลือก React ด้วย

Zac กำลังทวีตความคืบหน้าในการเขียนของเขาที่ @zgordon บน Twitter คุณยังสามารถได้ยิน Zac พูดคุยเกี่ยวกับ React บนพอดคาสต์ OSTraining

ในเนื้อหาที่ตัดตอนมาจากหนังสือนี้ Zac ให้ภาพรวมระดับสูงของ React และแนวคิดหลักบางประการ


React คืออะไร?

นอกกรอบ React เป็นไลบรารีสำหรับสร้างส่วนต่อประสานผู้ใช้

แม้ว่า React จะเป็นไลบรารี JavaScript แต่อินเทอร์เฟซที่สร้าง React นั้นไม่เชื่อเรื่องพระเจ้า

มีไลบรารีร่วมของ React หลายตัวเพื่อให้อินเทอร์เฟซที่คุณสร้างทำงานในเบราว์เซอร์ บนเซิร์ฟเวอร์ ในแอปพลิเคชันดั้งเดิม และแม้แต่ในสภาพแวดล้อม 360 และ VR ในหนังสือเล่มนี้ เราเน้นการทำงานกับ ReactDOM ซึ่งเป็นไลบรารีที่จัดการการเพิ่มอินเทอร์เฟซที่เราสร้างด้วย React ไปยังเว็บไซต์และแอปพลิเคชันฝั่งไคลเอ็นต์ ReactDomServer, ReactNative และ React360 เป็นไลบรารี่ที่คุณอาจต้องการสำรวจเพื่อใช้อินเทอร์เฟซ React ในสภาพแวดล้อมอื่นๆ

นอกเหนือจากการจัดเตรียมฟังก์ชันตัวช่วยสำหรับการสร้างอินเทอร์เฟซ สถาปัตยกรรมของ React ยังช่วยให้คุณจัดการกับการโต้ตอบกับอินเทอร์เฟซของคุณ ไม่ว่าจะเกี่ยวข้องกับการจัดการเหตุการณ์ การเรียก API การจัดการสถานะ การอัปเดตอินเทอร์เฟซ หรือการโต้ตอบที่ซับซ้อนมากขึ้น

React ไม่ได้ให้ฟังก์ชันตัวช่วยมากเท่ากับเฟรมเวิร์ก JavaScript บางตัว นี่เป็นส่วนใหญ่ว่าทำไมเราจึงเรียก React ว่าไลบรารี่และไม่ใช่เฟรมเวิร์ก คุณจะต้องเขียน JavaScript วานิลลาจำนวนมากเมื่อทำงานกับ React


อธิบายสถาปัตยกรรมส่วนประกอบตอบสนอง

คอมโพเนนต์เป็นโค้ดอิสระที่นำกลับมาใช้ใหม่ได้ (สร้างผ่านฟังก์ชันหรือคลาส)

React ใช้สถาปัตยกรรมส่วนประกอบสำหรับสร้างส่วนต่อประสานผู้ใช้และจัดระเบียบรหัส ไฟล์หลักสำหรับแอป React แบบธรรมดาอาจมีลักษณะดังนี้

 // นำเข้า React และส่วนประกอบอื่นๆ
นำเข้า React จาก 'react';
นำเข้า { render } จาก 'react-dom';
นำเข้าส่วนหัวจาก './Header';
นำเข้า MainContent จาก './MainContent';
นำเข้าส่วนท้ายจาก './Footer';

แอปฟังก์ชัน (){
  กลับ (
    <div className="app">
      <Header />
      <เนื้อหาหลัก />
      <ส่วนท้าย />
    </div>
 );
}

ReactDOM.render( <แอพ />, document.getElementById("root"));

เราสามารถเห็นส่วนประกอบบางส่วนที่ใช้งานได้ที่นี่ <Header />, <MainContent /> และ <Footer /> เป็นส่วนประกอบทั้งหมด ฟังก์ชัน App() ก็เป็นส่วนประกอบเช่นกัน และเราสามารถเห็นได้ในบรรทัดสุดท้ายของตัวอย่างนี้ว่าเราสามารถใช้ไลบรารี ReactDOM และวิธีการ ReactDOM.render() เพื่อจัดการการเพิ่ม UI ที่เราสร้างไปยังหน้าเว็บได้อย่างไร

หากเราเจาะลึกองค์ประกอบ <Header />, <MainContent /> และ <Footer /> เราน่าจะเห็นการใช้ส่วนประกอบเพิ่มเติมรวมถึงสิ่งที่ดูเหมือนมาร์กอัป HTML

 นำเข้า React จาก "react";
นำเข้าโฆษณาจาก "../Ad";
นำเข้าโลโก้จาก "../assets/logo.svg";

ส่งออกฟังก์ชันเริ่มต้น ส่วนหัว () {
กลับ (
<header className="app-header">
<โฆษณา />
<img src={logo} className="app-logo" alt="logo" />
<h1 className="app-title">ชื่อไซต์</h1>
</header>
);
}

ในองค์ประกอบ <Header /> ด้านบนนี้ เราจะเห็นว่าเรากำลังดึงองค์ประกอบอื่นที่เรียกว่า <Ad /> เข้ามา แอปพลิเคชัน React ส่วนใหญ่ประกอบด้วยการซ้อนองค์ประกอบหลายชั้นอย่างที่เราเห็นใน <App />, <Header /> และ <Ad />

เรายังเห็นการใช้องค์ประกอบ HTML ในโค้ดตอบโต้ของเรา สิ่งนี้เป็นไปได้ด้วยไลบรารีชื่อ JSX ซึ่งช่วยให้คุณเขียน “HTML markup” ลงใน JavaScript ของคุณได้โดยตรง เนื่องจากเราใช้ React เพื่อสร้างส่วนต่อประสานกับผู้ใช้ และส่วนต่อประสานผู้ใช้บนเว็บนั้นเกี่ยวข้องกับมาร์กอัป HTML จึงสมเหตุสมผลที่เราจะเห็นว่าองค์ประกอบ HTML เหมือนกับองค์ประกอบภายในองค์ประกอบ UI ของเรา เราจะสำรวจ JSX ในเชิงลึกในหนังสือเล่มนี้

หากเราดูโค้ดจากแอป React แบบง่ายที่สร้างโดยใช้ React 360 ซึ่งเป็นไลบรารี VR ของ React ส่วนประกอบจริงที่เราเรียกว่าจะแตกต่างออกไป แต่สถาปัตยกรรมส่วนประกอบยังคงมีอยู่

 นำเข้า React จาก 'react';
นำเข้า {
  ข้อความ,
  ดู,
  วีอาร์บัตตัน,
} จาก 'react-360';

สไลด์โชว์คลาสขยาย React.Component {
  // รหัสถูกลบเพื่อความกระชับ
  กลับ (
    <ดู style={styles.wrapper}>
      <ดู style={styles.controls}>
        <VrButton onClick={this.prevPhoto}>
          <ข้อความ>{'ก่อนหน้า'}</Text>
        </VrButton>
        <VrButton onClick={this.nextPhoto}>
         <ข้อความ>{'ถัดไป'}</Text>
        </VrButton>
      <ดู>
        <Text style={styles.title}>{current.title}</Text>
      </ดู>
    </ดู>
  );
}

โค้ดด้านบนสร้างมุมมอง 360 หลายชั้นโดยมีปุ่มและข้อความซ้อนทับอยู่ แม้ว่าโค้ดจริงอาจดูไม่สมเหตุสมผล แต่ควรชัดเจนว่าเรามีองค์ประกอบที่ซ้อนกันหลายอย่างซึ่งแสดงถึงมุมมอง ปุ่ม และข้อความ

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


อธิบายการไหลของข้อมูลตอบสนอง

React เป็นไปตามแบบแผนในการรับและตั้งค่าข้อมูลที่จุดสูงสุดที่จำเป็นในลำดับชั้นของส่วนประกอบเพื่อให้ข้อมูลส่งผ่านในทิศทางเดียวผ่านแอปพลิเคชัน ลองมาดูตัวอย่างนี้และจินตนาการถึงข้อมูลบางประเภทที่เราต้องการ สำหรับส่วนประกอบต่างๆ

 แอปฟังก์ชัน () {
  กลับ(
    <React.Fragment>
      <Header />
      <เนื้อหา />
      <แถบด้านข้าง />
      <ส่วนท้าย />
    </React.Fragment>
  );
}

ชื่อไซต์อาจต้องมีให้ใช้งานได้ทั้ง <Header /> และ <Footer /> เนื้อหาหลักสำหรับหน้านั้นจะต้องถูกส่งไปยัง <Content /> ข้อมูลวิดเจ็ตเพิ่มเติมบางอย่างอาจต้องไปที่ <แถบด้านข้าง />

 แอปฟังก์ชัน () {
  const siteTitle = getSiteTitle();
  วิดเจ็ต const = getWidgets ();
  const mainContent = getPageContent ();
  กลับ(
    <React.Fragment>
      <Header siteTitle={siteTitle} />
      <เนื้อหา mainContent={mainContent} />
      <วิดเจ็ตแถบด้านข้าง={วิดเจ็ต} />
      <ส่วนท้าย siteTitle={siteTitle} />
    </React.Fragment>
  );
}

แบบแผนของการสร้างชื่อแอตทริบิวต์และการกำหนดค่าให้กับพวกเขาเป็นวิธีที่เราส่งข้อมูลไปยังส่วนประกอบ

ตอนนี้ <Header /> และ <Footer /> สามารถเข้าถึง siteTitle แล้ว <Content /> สามารถเข้าถึง mainContent และ <Sidebar /> สามารถเข้าถึงวิดเจ็ตที่ต้องการได้

หมายเหตุสำคัญคือรูปแบบการส่งข้อมูลไปยังส่วนประกอบนี้จะส่งผ่านข้อมูลเพียงระดับเดียวเท่านั้น ส่วนประกอบภายใน <Header /> จะไม่สามารถเข้าถึง siteTitle ได้โดยอัตโนมัติ

 ส่วนหัวของฟังก์ชัน (อุปกรณ์ประกอบฉาก) {
  กลับ(
    <header>
      <p>สามารถดู {props.siteTitle} ได้ที่นี่</p>
      <PageHeader siteTitle={props.siteTitle} />
      <PageSubHeader />
    </header>
  );
}

คุณจะเห็นได้ว่าใน <Header /> เราสามารถเรียก props.siteTitle และเข้าถึงค่านั้นที่เราส่งเข้าไปได้ อย่างไรก็ตาม หากเราต้องการเข้าถึง siteTitle ภายในองค์ประกอบ <PageHeader /> เราจะต้องส่งข้อมูลนั้นด้วยตนเองเช่นกัน

เมื่อส่วนประกอบได้รับค่าเป็นพร็อพ ก็ไม่ควรแก้ไข อุปกรณ์ประกอบฉากควรผ่านโครงสร้างส่วนประกอบเป็นข้อมูลที่ไม่เปลี่ยนรูป เพื่อให้แน่ใจว่าส่วนประกอบใดๆ ที่อ้างอิงพร็อพ อ้างอิงค่าเดียวกันกับที่เป็นพาเรนต์ของส่วนประกอบย่อย

ค่าของ prop ควรเปลี่ยนเฉพาะในส่วนประกอบที่ตั้งค่าของ prop เดิมและเริ่มส่งต่อผ่านโครงสร้างส่วนประกอบ ในโค้ดตัวอย่างด้านบนของเรา คอมโพเนนต์ <App /> สามารถเปลี่ยนค่าของ siteTitle ได้ แต่คอมโพเนนต์ <Header /> หรือ <PageHeader /> ไม่ควร

เพื่อให้เข้าใจถึงกระแสของการอัพเดทข้อมูลแบบไดนามิกในแอป React นั้นเกี่ยวข้องกับการอภิปรายเกี่ยวกับสถานะและวิธีที่ตัวจัดการเหตุการณ์สามารถส่งผ่านเป็นอุปกรณ์ประกอบฉากได้


อธิบายสถานะส่วนประกอบตอบสนอง

ตามที่เราได้เรียนรู้ ข้อมูลไหลลงมาไม่เปลี่ยนแปลงผ่านส่วนประกอบเป็นอุปกรณ์ประกอบฉาก ข้อมูลถูกกำหนดไว้ที่องค์ประกอบที่สูงที่สุดในแผนผังที่จำเป็นสำหรับส่วนประกอบย่อยทั้งหมดในการส่งข้อมูลที่ต้องการเป็นอุปกรณ์ประกอบฉาก

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

ในการติดตามข้อมูลที่เปลี่ยนแปลงใน React เรามีวัตถุสถานะ React และชุดฟังก์ชันตัวช่วยเพื่ออัปเดตค่าสถานะ

นี่คือตัวอย่างของตัวนับที่จะอัปเดตตัวเอง ค่าของตัวนับคือค่าที่เป็นไดนามิกภายในส่วนประกอบนี้ ดังนั้นจึงเป็นตัวอย่างที่ดีว่าเมื่อใดควรพึ่งพาสถานะ โปรดทราบว่าในการสร้างส่วนประกอบที่มีสถานะ เราต้องใช้คลาส JavaScript มากกว่าฟังก์ชัน

 ตัวนับคลาสขยายส่วนประกอบ {
  รัฐ= {
    เคาน์เตอร์:0
  };

  handleCount = () => {
    this.setState({
      เคาน์เตอร์: this.state.counter + 1
    });
  };

  เรนเดอร์ () {
    กลับ (
      <div>
        <h1>{this.state.counter}</h1>
        <button onClick={this.handleCount}>Count Up!!</button>
      </div>
    );
  }
}

ตอนนี้สิ่งสำคัญคือต้องสังเกตว่าสถานะนี้กำหนดขอบเขตไว้เฉพาะองค์ประกอบนี้ ค่าของสถานะในตัวนับจะไม่สามารถใช้ได้กับส่วนประกอบย่อยหรือพาเรนต์

ดังนั้นในตัวอย่างที่ซับซ้อนมากขึ้น ดังตัวอย่างด้านล่าง เราจะต้องส่งค่าของตัวนับลงเป็นตัวประกอบไปยังองค์ประกอบย่อย

 ตัวนับคลาสขยายส่วนประกอบ {
  รัฐ= {
    นับ:0
  };

  handleCount = () => {
    this.setState({
      นับ: this.state.count + 1
    });
  };

  เรนเดอร์ () {
    กลับ (
      <div>
        <PageHeader count={this.state.count} />
        <button onClick={this.handleCount}>Count Up!!</button>
      </div>
    );
  }
}

<PageHeader /> count prop ได้รับการอัปเดตทุกครั้งที่เราอัปเดตสถานะในคอมโพเนนต์ <Counter />

 ฟังก์ชั่น PageHeader (อุปกรณ์ประกอบฉาก) {
  กลับ <h1>{props.count}</h1>; 
}

ข้อดีของวิธีนี้คือทุกครั้งที่มีการอัปเดตสถานะ ค่าใหม่จะถูกส่งต่อไปยังส่วนประกอบย่อยโดยอัตโนมัติด้วยค่าของ prop ที่ตั้งค่าเป็นสถานะ

ซึ่งช่วยให้เรามีความจริงเพียงจุดเดียวสำหรับข้อมูลแบบไดนามิก แหล่งที่มาของความจริงคือคุณค่าในสถานะ จัดการจากองค์ประกอบเดียว อินสแตนซ์ทั้งหมดของค่านี้ในองค์ประกอบย่อยเป็นค่าที่ไม่เปลี่ยนรูปที่ได้รับเป็นอุปกรณ์ประกอบฉากที่ไม่ควรเปลี่ยนนอกองค์ประกอบนี้

ส่วนประกอบที่ปรากฏเหนือส่วนประกอบนี้ในลำดับชั้นจะไม่สามารถเข้าถึงข้อมูลนี้ได้ เนื่องจากจะถูกส่งผ่านผ่านอุปกรณ์ประกอบฉากเท่านั้น เราเห็นอีกครั้งว่าทำไมเราถึงพยายามตั้งค่าและจัดการสถานะจากส่วนประกอบที่สูงกว่าในลำดับชั้น เพื่อให้ข้อมูลพร้อมใช้งานสำหรับทุกสิ่งที่ต้องการ

มีรูปแบบสถาปัตยกรรมอื่นๆ เช่น ส่วนประกอบที่มีลำดับสูงกว่าและ API บริบท ซึ่งหลีกเลี่ยงความจำเป็นในการส่งอุปกรณ์ประกอบฉากจำนวนมากผ่านแอปของคุณด้วยตนเอง เราจะสำรวจสิ่งเหล่านี้ในเชิงลึกมากขึ้นในภายหลัง สำหรับตอนนี้ เราต้องการให้แน่ใจว่าเราเข้าใจภาพรวมระดับสูงเกี่ยวกับการทำงานของสิ่งต่าง ๆ โดยทั่วไปก่อนที่เราจะเริ่มใช้ทางลัด

การอัพเดตสถานะส่วนประกอบใน React

จะเกิดอะไรขึ้นเมื่อเราต้องการทริกเกอร์สถานะเพื่ออัปเดตจากองค์ประกอบย่อย

ตัวอย่างเช่น ลองนึกภาพตัวอย่างด้านบนว่าเราต้องการส่วนประกอบ <ปุ่ม /> แทนที่จะเป็นปุ่มฮาร์ดโค้ดในองค์ประกอบ <Counter /> หลักของเราหรือไม่ นี่เป็นเรื่องปกติธรรมดาในแอปที่ซับซ้อน

วิธีแก้ปัญหาในโลก React คือการส่งผ่านฟังก์ชันตัวจัดการเหตุการณ์ที่อัพเดตสถานะด้วย setState down เป็นอุปกรณ์ประกอบฉาก จากนั้นสามารถเรียกได้จากองค์ประกอบย่อยใด ๆ แต่การดำเนินการจะเกิดขึ้นในองค์ประกอบดั้งเดิมที่กำหนดสถานะและมีความสามารถในการอัปเดตเช่นกัน มีรูปแบบอื่นสำหรับสิ่งนี้ แต่แนวทางนี้เป็นพื้นฐานที่สุด

หากคุณไม่คุ้นเคยกับฟังก์ชันส่งผ่านเป็นพารามิเตอร์ แสดงว่า JavaScript วนิลาที่ถูกต้องสมบูรณ์

เมื่อสถานะได้รับการอัปเดตแล้ว สถานะจะถูกส่งผ่านไปยังลำดับชั้นของส่วนประกอบผ่านอุปกรณ์ประกอบฉาก

นี่คือตัวอย่างที่จะมีลักษณะเป็นอย่างไร

 ตัวนับคลาสขยายส่วนประกอบ {
  รัฐ= {
    นับ:0
  };

  handleCount = () => {
    this.setState({
      นับ: this.state.count + 1
    });
  };

  เรนเดอร์ () {
    กลับ (
      <div>
        <PageHeader count={this.state.count} />
        <ปุ่ม handleCount={this.handleCount} />        
      </div>
    );
  }
}

ฟังก์ชั่น PageHeader (อุปกรณ์ประกอบฉาก) { 
  กลับ( 
    <h1>{props.count}</h1>
 ); 
}

ปุ่มฟังก์ชั่น (อุปกรณ์ประกอบฉาก) {
  กลับ(
    <button onClick={props.handleCount}>Count Up!!</button>  
  );
}

ที่นี่เราสามารถดูตัวอย่างง่ายๆ ว่า React จัดการกับกระแสข้อมูลอย่างไร มีจุดความจริงเพียงจุดเดียวสำหรับข้อมูล ที่มีอยู่ในชุดสถานะและอัปเดตจากองค์ประกอบเดียว ข้อมูลถูกส่งไปในทางเดียวผ่านแผนผังองค์ประกอบที่ซ้อนกันผ่านอุปกรณ์ประกอบฉาก

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

เมื่อเรากำหนดค่าของพร็อพให้กับบางสิ่งจากสถานะ เช่นด้านล่าง ค่าของพร็อพนั้นจะอัปเดตโดยอัตโนมัติทุกครั้งที่สถานะเปลี่ยนแปลง

 <ตัวนับ PageHeader={this.state.count} />

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

อาจใช้เวลาสักครู่ในการทำความคุ้นเคยขึ้นอยู่กับว่าคุณเคยประสบปัญหาเช่นนี้กับ JavaScript ในอดีตอย่างไร อย่างไรก็ตาม ทั้งหมดนี้ควรเป็นจุดเริ่มต้นที่ดีสำหรับเราที่จะสามารถเจาะลึกลงไปในการอธิบาย React ได้