ให้เรตสมาชิก: 3 / 5

ดาวใช้งานดาวใช้งานดาวใช้งานดาวไม่ได้ใช้งานดาวไม่ได้ใช้งาน
 

Lifting State Up

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

     เราจะเริ่มต้นด้วย Elements ที่ชื่อว่า BoilingVerdict และแสดงค่าอุณหภูมิ เมื่อน้ำเดือด :

function BoilingVerdict(props) {
  if (props.celsius >= 100) {
    return <p>The water would boil.</p>;
  }
  return <p>The water would not boil.</p>;
}

     จากนั้นเราจะสร้าง Component ที่เรียกว่าเครื่องคิดเลข มันทำให้ <input> ที่ช่วยให้เราสามารถป้อนอุณหภูมิและเก็บค่าใน this.state.temperature

     นอกจากนี้ จะแสดงค่า BoilingVerdict สำหรับค่า Input ในปัจจุบัน ข้างล่างนี้จะเป็นโค้ดอุณหภูมิน้ำ :

class Calculator extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {temperature: ''};
  }

  handleChange(e) {
    this.setState({temperature: e.target.value});
  }

  render() {
    const temperature = this.state.temperature;
    return (
      <fieldset>
        <legend>Enter temperature in Celsius:</legend>
        <input
          value={temperature}
          onChange={this.handleChange} />
        <BoilingVerdict
          celsius={parseFloat(temperature)} />
      </fieldset>
    );
  }
}

     ผลที่ได้มีดังนี้ : ถ้าเรากรอกอุณหภูมิ 10 ลงไป ก็จะแสดงค่าว่า not boil แต่ถ้าเรากรอก 100 ลงไป จะแสดงค่า boil

temptemp

 

การเพิ่ม Input ที่สอง

     ต่อไปเราจะให้ข้อกำหนดใหม่นอกเหนือจากการป้อนค่า Celsius เราจะมี Input ของ Fahrenheit และจะถูกเก็บไว้ในข้อมูลตรงกัน เราจะเริ่มจากการดึง Component TemperatureInput จาก Calculator โดยเราจะเพิ่มสเกลใหม่ลงไป อาจจะเป็น "C" หรือ "F" :

const scaleNames = {
  c: 'Celsius',
  f: 'Fahrenheit'
};

class TemperatureInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {temperature: ''};
  }

  handleChange(e) {
    this.setState({temperature: e.target.value});
  }

  render() {
    const temperature = this.state.temperature;
    const scale = this.props.scale;
    return (
      <fieldset>
        <legend>Enter temperature in {scaleNames[scale]}:</legend>
        <input value={temperature}
               onChange={this.handleChange} />
      </fieldset>
    );
  }
}

     ตอนนี้เราสามารถเปลี่ยน Calculator เพื่อแสดงอุณหภูมิสองแบบแยกกันได้ :

class Calculator extends React.Component {
  render() {
    return (
      <div>
        <TemperatureInput scale="c" />
        <TemperatureInput scale="f" />
      </div>
    );
  }
}

     ผลลัพธ์ที่ได้ : จะได้ Input สองช่อง

temp2temp2

     ตอนนี้เรามี Input สองตัว แต่เมื่อเราป้อนอุณหภูมิในรายการใดรายการหนึ่งข้อมูลอื่น ๆ จะไม่อัปเดต สิ่งนี้ขัดแย้งกับข้อกำหนด : ดังนั้นเราต้องทำให้ข้อมูลตรงกัน

     เรายังไม่สามารถแสดง BoilingVerdict จาก Calculator ได้ เพราะว่า Calculator ไม่ทราบอุณหภูมิปัจจุบัน เพราะมันถูกซ่อนอยู่ภายใน TemperatureInput

 

การเขียนฟังก์ชั่นการแปลงค่า

     ขั้นแรกเราจะเขียนสองฟังก์ชั่นเพื่อแปลงจาก Celsius เป็น Fahrenheit และมีการแสดงค่ากลับกัน :

function toCelsius(fahrenheit) {
  return (fahrenheit - 32) * 5 / 9;
}

function toFahrenheit(celsius) {
  return (celsius * 9 / 5) + 32;
}

     ฟังก์ชันทั้งสอง แปลงตัวเลข เราจะเขียนฟังก์ชันอื่นที่ใช้สตริง temperature และฟังก์ชันแปลงเป็น Arguments และส่งกลับสตริง เราจะใช้มันในการคำนวณค่าของหนึ่ง Input โดยใช้ Input อื่น ๆ ส่งกลับสตริงที่ว่างเปล่าใน temperature ที่ไม่ถูกต้องและจะให้ผลลัพธ์ปัดเศษทศนิยมที่สาม :

function tryConvert(temperature, convert) {
  const input = parseFloat(temperature);
  if (Number.isNaN(input)) {
    return '';
  }
  const output = convert(input);
  const rounded = Math.round(output * 1000) / 1000;
  return rounded.toString();
}

     ตัวอย่างเช่น tryConvert ('abc', toCelsius) จะ return ค่าว่างและ tryConvert ('10 .22 ', toF) จะแสดงผลลัพธ์ '50 .396'

 

Lifting State Up

     ตอนนี้ทั้งสอง Component TemperatureInput อิสระเก็บค่าในสถานะ Local :

class TemperatureInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {temperature: ''};
  }

  handleChange(e) {
    this.setState({temperature: e.target.value});
  }

  render() {
    const temperature = this.state.temperature;
    // ...  

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

     ใน React การแบ่งปัน state ทำได้โดยการเคลื่อนย้ายไปยัง parent ร่วมกันที่ใกล้เคียงที่สุดของ Component ที่จำเป็นต้องใช้ นี้เรียกว่า "Lifting State Up" เราจะลบสถานะภายในออกจาก TemperatureInput และย้ายไปยัง Calculator แทน

     สำหรับอุณหภูมิปัจจุบันใน Input ทั้งสอง สามารถสั่งให้ทั้งสองมีค่าที่สอดคล้องกัน เนื่องจากส่วนกำหนดค่าของส่วนประกอบ TemperatureInput ทั้งสองมาจาก Component Calculator หลักเดียวกัน Input ทั้งสองจะซิงค์กันอยู่เสมอ

 

มาดูกันใน Step ต่อไปเลยดีกว่า

     ขั้นแรกเราจะแทนที่ this.state.temperature ด้วย this.props.temperature ใน Component TemperatureInput ตอนนี้สมมติว่า this.props.temperature มีอยู่แล้วแม้ว่าเราจะต้องส่งต่อจาก Calculator ในอนาคต :

render() {
    // Before: const temperature = this.state.temperature;
    const temperature = this.props.temperature;
    // ...

     เรารู้ว่า props เป็นแบบอ่านอย่างเดียว เมื่อ Temperature อยู่ใน Local state TemperatureInput สามารถเรียกใช้ this.setState() เพื่อเปลี่ยนได้ อย่างไรก็ตามตอนนี้ Temperature ที่มาจาก parent เป็น props TemperatureInput ที่ไม่มีการควบคุม

     ใน React จะแก้ไขได้โดยการทำให้ Component เป็นตัวควบคุม เช่นเดียวกับ DOM <input> ยอมรับทั้ง value และ onChange prop ดังนั้น TemperatureInput ที่กำหนดเองจึงสามารถรับ Temperature ทั้งสอง onTemperatureChange จาก Calculator หลักได้

     ตอนนี้เมื่อ TemperatureInput ต้องการที่จะปรับปรุงอุณหภูมิ จะมีการเรียก this.props.onTemperatureChange :

  handleChange(e) {
    // Before: this.setState({temperature: e.target.value});
    this.props.onTemperatureChange(e.target.value);
    // ...

     Example โค้ดคำนวนอุณหภูมิที่สมบูรณ์แล้ว :

class Calculator extends React.Component {
  constructor(props) {
    super(props);
    this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
    this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
    this.state = {temperature: '', scale: 'c'};
  }

  handleCelsiusChange(temperature) {
    this.setState({scale: 'c', temperature});
  }

  handleFahrenheitChange(temperature) {
    this.setState({scale: 'f', temperature});
  }

  render() {
    const scale = this.state.scale;
    const temperature = this.state.temperature;
    const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;
    const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;

    return (
      <div>
        <TemperatureInput
          scale="c"
          temperature={celsius}
          onTemperatureChange={this.handleCelsiusChange} />
        <TemperatureInput
          scale="f"
          temperature={fahrenheit}
          onTemperatureChange={this.handleFahrenheitChange} />
        <BoilingVerdict
          celsius={parseFloat(celsius)} />
      </div>
    );
  }
}

     ผลลัพธ์ที่ได้ : เมื่อกรอกอุณหภูมิลงไปในช่อง Celsius จะมีการคำนวนค่า Fahrenheit และแสดงออกมาในช่อง Output

 

temp3temp3

 

 

 

ข้อมูลอ้างอิง : https://reactjs.org

กระทู้ล่าสุดจากเว็บบอร์ด
หัวข้อกระทู้
ตอบ
เปิดดู
ล่าสุด
ทำความรู้การปิดบัญชี เพื่อให้ทราบผลการดำเนินไปประกอบในการตัดสินใจวางแผนธุรกิจ
โดย nutchasn พฤ 30 ม.ค. 2020 5:06 pm บอร์ด Accounting software & ERP โปรแกรมบัญชี ระบบอีอาร์พี
0
41
พฤ 30 ม.ค. 2020 5:06 pm โดย nutchasn
ทำความเข้าใจในการปิดงบบัญชี เพิ่อให้เป็นการปิดงบที่สมบูรณ์
โดย nutchasn พฤ 30 ม.ค. 2020 4:36 pm บอร์ด Accounting software & ERP โปรแกรมบัญชี ระบบอีอาร์พี
0
29
พฤ 30 ม.ค. 2020 4:36 pm โดย nutchasn
อยากทราบวิธีการดึงค่าเลขเวอร์ชั่นในไฟล์ XML ของ components joomla
โดย jamepiyawat พฤ 30 ม.ค. 2020 3:28 pm บอร์ด Joomla Development
3
72
พฤ 30 ม.ค. 2020 5:34 pm โดย tsukasaz
อัพเดทกันหรือยัง! Joomla 3.9.15 ปรับปรุงความปลอดภัยและแก้ไขข้อผิดพลาดต่างๆ
โดย tsukasaz พฤ 30 ม.ค. 2020 11:37 am บอร์ด MindPHP News & Feedback
0
22
พฤ 30 ม.ค. 2020 11:37 am โดย tsukasaz
วิธีการนำข้อความที่ผู้ใช้กรอกให้เข้าไปอยู่ในไฟล์ pdf ด้วยภาษา php
โดย jamepiyawat พ 29 ม.ค. 2020 6:53 pm บอร์ด PHP Knowledge
0
44
พ 29 ม.ค. 2020 6:53 pm โดย jamepiyawat
ติดตั้ง module flaskwebgui ไม่ได้ครับ
โดย benzas00123 พ 29 ม.ค. 2020 6:53 pm บอร์ด Programming - C/C++ & java & Python
2
50
พฤ 30 ม.ค. 2020 11:52 am โดย jirawoot
ความรู้พื้นฐานเกี่ยวกับบัญชีแยกประเภท
โดย nutchasn พ 29 ม.ค. 2020 6:32 pm บอร์ด Accounting software & ERP โปรแกรมบัญชี ระบบอีอาร์พี
0
24
พ 29 ม.ค. 2020 6:32 pm โดย nutchasn
Pillow library ฟังก์ชั่น Image.new() ฟังก์ชั่นที่ใช้สำหรับการสร้างไฟล์รูปภาพ
โดย benzas00123 พ 29 ม.ค. 2020 6:21 pm บอร์ด Python Knowledge
0
21
พ 29 ม.ค. 2020 6:21 pm โดย benzas00123
ความรู้พื้นฐานเกี่ยวกับงบทดลอง (Taial Balance)
โดย nutchasn พ 29 ม.ค. 2020 6:00 pm บอร์ด Accounting software & ERP โปรแกรมบัญชี ระบบอีอาร์พี
0
25
พ 29 ม.ค. 2020 6:00 pm โดย nutchasn
Pillow library ฟังก์ชั่น ImageDraw() ฟังก์ชั่นสำหรับการเพิ่มตัวอักษรเข้าไปในภาพ
โดย benzas00123 พ 29 ม.ค. 2020 5:52 pm บอร์ด Python Knowledge
0
31
พ 29 ม.ค. 2020 5:52 pm โดย benzas00123
การปรับปรุงค่าใช้จ่ายจ่ายล่วงหน้า (Prepaid expenses)
โดย nutchasn พ 29 ม.ค. 2020 5:29 pm บอร์ด Accounting software & ERP โปรแกรมบัญชี ระบบอีอาร์พี
0
21
พ 29 ม.ค. 2020 5:29 pm โดย nutchasn
วิธีการเขียน php สำหรับตรวจสอบหมายเลขบัตรประชาชนว่ามีความถูกต้องหรือไม่
โดย Ittichai_chupol พ 29 ม.ค. 2020 5:24 pm บอร์ด PHP Knowledge
0
50
พ 29 ม.ค. 2020 5:24 pm โดย Ittichai_chupol
ทำความรู้จักกับชนิดข้อมูลใน SQL
โดย nutchasn พ 29 ม.ค. 2020 4:38 pm บอร์ด Accounting software & ERP โปรแกรมบัญชี ระบบอีอาร์พี
0
35
พ 29 ม.ค. 2020 4:38 pm โดย nutchasn
วิธีการปรับปรุงรายได้รับล่วงหน้า (Deferred Income)
โดย nutchasn พ 29 ม.ค. 2020 3:38 pm บอร์ด Accounting software & ERP โปรแกรมบัญชี ระบบอีอาร์พี
0
26
พ 29 ม.ค. 2020 3:38 pm โดย nutchasn
ผมไม่สามารถใช้ module tkinter ได้ครับ
โดย benzas00123 พ 29 ม.ค. 2020 2:04 pm บอร์ด Programming - C/C++ & java & Python
10
94
พฤ 30 ม.ค. 2020 10:15 am โดย benzas00123
การปรับปรุงรายได้ค้างรับ (Accrued Revenue)
โดย nutchasn พ 29 ม.ค. 2020 2:09 pm บอร์ด Accounting software & ERP โปรแกรมบัญชี ระบบอีอาร์พี
0
26
พ 29 ม.ค. 2020 2:09 pm โดย nutchasn
ปิด textbox เพื่อให้ไม่สามารถแก้ไขข้อมูลได้ด้วย radio button
โดย benzas00123 พ 29 ม.ค. 2020 11:31 am บอร์ด HTML CSS
0
38
พ 29 ม.ค. 2020 11:31 am โดย benzas00123
อยากทราบวิธีการ insert ข้อมูลในตอนติดตั้ง Extension ของ phpbb
โดย Ittichai_chupol พ 29 ม.ค. 2020 11:03 am บอร์ด Programming - PHP
1
50
พ 29 ม.ค. 2020 11:08 am โดย thatsawan
เจอของจริง
โดย noppadonsk พ 29 ม.ค. 2020 10:58 am บอร์ด พูดคุยเรื่องทั่วไป จับฉ่าย
0
43
พ 29 ม.ค. 2020 10:58 am โดย noppadonsk
อยากทราบวิธีแยกข้อมูลที่เรียงกันอย่างไม่เป็นระเบียบเข้า DB
โดย meetingyou999 อ 28 ม.ค. 2020 10:37 pm บอร์ด Programming - PHP
0
65
อ 28 ม.ค. 2020 10:37 pm โดย meetingyou999