ให้เรตสมาชิก: 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

กระทู้ล่าสุดจากเว็บบอร์ด
หัวข้อกระทู้
ตอบ
เปิดดู
ล่าสุด
รูปแบบการทำงานของ NAT มีอะไรบ้าง
โดย Patcharanan.0399 ศ 20 เม.ย. 2018 5:14 pm บอร์ด Share Knowledge
0
5
ศ 20 เม.ย. 2018 5:14 pm โดย Patcharanan.0399
ส่วนที่ไม่เข้าใจในบทความ Module MD Client History
โดย alisa93 ศ 20 เม.ย. 2018 4:56 pm บอร์ด Mobile Programming - Android, iOS, Window Phone
2
8
ศ 20 เม.ย. 2018 5:56 pm โดย alisa93
Loopback คืออะไร
โดย Patcharanan.0399 ศ 20 เม.ย. 2018 4:21 pm บอร์ด Share Knowledge
0
6
ศ 20 เม.ย. 2018 4:21 pm โดย Patcharanan.0399
สอบถามเรื่อง SQL การ SELECT id
โดย AePongsak ศ 20 เม.ย. 2018 4:21 pm บอร์ด ปัญหาการใช้ phpBB3, SMF, Joomla, Wordpress, CMS CRM
5
15
ศ 20 เม.ย. 2018 5:05 pm โดย AePongsak
Q - ติดตั้งโมดูลแล้วไฟล์ภาษาหาย
โดย Parichat ศ 20 เม.ย. 2018 3:52 pm บอร์ด Joomla Development
2
12
ศ 20 เม.ย. 2018 4:20 pm โดย Parichat
Q - ทำ Drop Down ในหน้าผู้ดูแลระบบของโมดูล
โดย Parichat ศ 20 เม.ย. 2018 1:22 pm บอร์ด Joomla Development
6
28
ศ 20 เม.ย. 2018 6:59 pm โดย Parichat
ผมสงใสทำไมรีโมทแอร์ ทำไมถึงต้องอยุ่ข้างประตู
โดย nuattawoot ศ 20 เม.ย. 2018 12:58 am บอร์ด พูดคุยเรื่องทั่วไป จับฉ่าย
2
37
ศ 20 เม.ย. 2018 9:47 am โดย tsukasaz
Normal Form ของ Normalization มีอะไรบ้าง
โดย Patcharanan.0399 พฤ 19 เม.ย. 2018 6:37 pm บอร์ด Share Knowledge
0
6
พฤ 19 เม.ย. 2018 6:37 pm โดย Patcharanan.0399
Q - import ฐานข้อมูลมาแต่ Error
โดย Parichat พฤ 19 เม.ย. 2018 5:55 pm บอร์ด SQL - Database
2
24
พฤ 19 เม.ย. 2018 6:43 pm โดย Parichat
ทำไมต้องมี IPv6 ....?
โดย Patcharanan.0399 พฤ 19 เม.ย. 2018 3:04 pm บอร์ด Share Knowledge
0
16
พฤ 19 เม.ย. 2018 3:04 pm โดย Patcharanan.0399
ต้องการใส่เสียงลงใน application
โดย Oley Rujisak พฤ 19 เม.ย. 2018 1:12 pm บอร์ด Mobile Application Developing- Android, iOS
0
10
พฤ 19 เม.ย. 2018 1:12 pm โดย Oley Rujisak
มาแล้ว Joomla 3.8.7 อัพเดทล่าสุด แก้ไข Bug ต่างๆ และปรับปรุงระบบให้ดีขึ้น
โดย tsukasaz พฤ 19 เม.ย. 2018 11:09 am บอร์ด PHP News
0
14
พฤ 19 เม.ย. 2018 11:09 am โดย tsukasaz
3-way Handshake (ทรีเวย์ แฮนเชค)คืออะไร
โดย Patcharanan.0399 พ 18 เม.ย. 2018 6:04 pm บอร์ด Share Knowledge
0
16
พ 18 เม.ย. 2018 6:04 pm โดย Patcharanan.0399
TCP (ทีซีพี) และ UDP (ยูดีพี) แตกต่างกันอย่างไร
โดย Patcharanan.0399 พ 18 เม.ย. 2018 5:46 pm บอร์ด Share Knowledge
1
23
พฤ 19 เม.ย. 2018 3:50 am โดย mindphp
ICMP Protocol (ไอซีเอ็มพี โปรโตคอล) คืออะไร
โดย Patcharanan.0399 พ 18 เม.ย. 2018 5:24 pm บอร์ด Share Knowledge
0
11
พ 18 เม.ย. 2018 5:24 pm โดย Patcharanan.0399
ไม่สามารถติดตั้ง selenium v.2.9.1 ได้
โดย Patcharanan.0399 พ 18 เม.ย. 2018 4:35 pm บอร์ด ถาม - ตอบ คอมพิวเตอร์
7
44
พฤ 19 เม.ย. 2018 3:45 am โดย mindphp
หาคนสอน Dreamweaver php+mySQL ด่วน!
โดย dettana พ 18 เม.ย. 2018 2:04 pm บอร์ด Programming - PHP
0
17
พ 18 เม.ย. 2018 2:04 pm โดย dettana
ODBMS (โอดีบีเอ็มเอส) และ RDBMS (อาดีบีเอ็มเอส) แตกต่างกันอย่างไร
โดย Patcharanan.0399 อ 17 เม.ย. 2018 5:11 pm บอร์ด Share Knowledge
0
22
อ 17 เม.ย. 2018 5:11 pm โดย Patcharanan.0399
วิธีการปรับปรุงงบการเงินที่ถูกต้อง
โดย thatsawan อ 17 เม.ย. 2018 4:24 pm บอร์ด ถาม - ตอบ ธุรกิจ กฏหมาย ภาษี บัญชี
0
20
อ 17 เม.ย. 2018 4:24 pm โดย thatsawan
trial balance เดือน 12 (31 ธันวาคม) กับ ตอนปิดงบปี ต้องเหมือนกันหรือตรงกันไหม
โดย thatsawan อ 17 เม.ย. 2018 3:59 pm บอร์ด ถาม - ตอบ ธุรกิจ กฏหมาย ภาษี บัญชี
0
13
อ 17 เม.ย. 2018 3:59 pm โดย thatsawan