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

กระทู้ล่าสุดจากเว็บบอร์ด
หัวข้อกระทู้
ตอบ
เปิดดู
ล่าสุด
Pillow library ปรับขนาดรูปเป็นเปอร์เซ็นเพื่อนำไปใช้งานได้สะดวก
โดย benzas00123 ส 18 ม.ค. 2020 5:25 pm บอร์ด Python Knowledge
0
74
ส 18 ม.ค. 2020 5:25 pm โดย benzas00123
Pillow library Optimize รูปภาพเพื่อให้มีขนาดของข้อมูลที่เล็กลง
โดย benzas00123 ส 18 ม.ค. 2020 2:53 pm บอร์ด Python Knowledge
0
218
ส 18 ม.ค. 2020 2:53 pm โดย benzas00123
ตัวช่วยในการคำนวณแคลอรี่สำหรับผู้ที่รักการออกกำลังกาย
โดย prmindphp ส 18 ม.ค. 2020 11:50 am บอร์ด MindPHP News & Feedback
0
210
ส 18 ม.ค. 2020 11:50 am โดย prmindphp
เราจะเก็บรูปข้อมูลของรูปลง database เราจะใช้ data type อะไรครับ
โดย benzas00123 ส 18 ม.ค. 2020 11:31 am บอร์ด SQL - Database
2
232
ส 18 ม.ค. 2020 1:17 pm โดย benzas00123
อยากทราบวิธีการแก้ไขปัญหาการ อัพโหลดไฟล์ excel แล้วไม่รองรับภาษาไทย
โดย Ittichai_chupol ศ 17 ม.ค. 2020 5:58 pm บอร์ด Programming - PHP
7
202
จ 20 ม.ค. 2020 2:05 pm โดย saravana
ต้องการนับจำนวนอักษรเเละตัดอักษรที่เกิน มีปัญหากับภาษาไทย
โดย thatsawan ศ 17 ม.ค. 2020 5:18 pm บอร์ด Programming - C/C++ & java & Python
0
75
ศ 17 ม.ค. 2020 5:18 pm โดย thatsawan
สอบถามครับ ลูปค่าออกมาแล้วต้องการให้มันเก็บค่าในตัวแปร ต้องทำยังไงครับ
โดย chatee supasand ศ 17 ม.ค. 2020 3:51 pm บอร์ด Programming - C/C++ & java & Python
3
172
ศ 17 ม.ค. 2020 5:19 pm โดย thatsawan
อยากทราบวิธีก่ารเปิด exe ใน ubutu เวอชั่น 14
โดย Ittichai_chupol ศ 17 ม.ค. 2020 2:33 pm บอร์ด Programming - PHP
2
184
ศ 17 ม.ค. 2020 4:14 pm โดย Ittichai_chupol
วิธีการสร้างระบบชำระเงินด้วย omise โดยใช้ php
โดย Ittichai_chupol พฤ 16 ม.ค. 2020 6:53 pm บอร์ด PHP Knowledge
0
122
พฤ 16 ม.ค. 2020 6:53 pm โดย Ittichai_chupol
Pillow library กับการ เปลี่ยนนามสกุล img ทีเดียวหลายๆ file
โดย benzas00123 พฤ 16 ม.ค. 2020 5:45 pm บอร์ด Python Knowledge
0
67
พฤ 16 ม.ค. 2020 5:45 pm โดย benzas00123
Pillow library ในการจัดการและประมวลผลรูปภาพ
โดย benzas00123 พฤ 16 ม.ค. 2020 5:04 pm บอร์ด Python Knowledge
0
126
พฤ 16 ม.ค. 2020 5:04 pm โดย benzas00123
ความแตกต่างระหว่าง visibility: hidden; กับ display: none;
โดย Ittichai_chupol พ 15 ม.ค. 2020 6:44 pm บอร์ด CSS Knowledge
0
168
พ 15 ม.ค. 2020 6:44 pm โดย Ittichai_chupol
ตัวอย่าง การ Query ข้อมูลทีเป็นที่ได้ผลการค้นหา
โดย mindphp พ 15 ม.ค. 2020 6:40 pm บอร์ด Programming - C/C++ & java & Python
0
85
พ 15 ม.ค. 2020 6:40 pm โดย mindphp
สอบถามครับ ทำไมสร้างตารางฐานข้อมูลแล้ว มันไม่ใน ใน pg
โดย chatee supasand พ 15 ม.ค. 2020 5:55 pm บอร์ด Programming - C/C++ & java & Python
4
118
พ 15 ม.ค. 2020 6:07 pm โดย thatsawan
ขอสอบถาม error ของ flask ครับ
โดย benzas00123 พ 15 ม.ค. 2020 10:44 am บอร์ด Programming - C/C++ & java & Python
4
119
พ 15 ม.ค. 2020 10:53 am โดย benzas00123
สอบถาม code ของ Flask หน่อยครับว่ามันเอาไว้ใช้ทำอะไร
โดย benzas00123 อ 14 ม.ค. 2020 4:50 pm บอร์ด Programming - C/C++ & java & Python
3
134
พ 15 ม.ค. 2020 5:54 am โดย mindphp
วิธีการเพิ่มส่วนการแสดงในหน้าสมัครสมาชิกของ เว็บบอร์ด phpbb
โดย Ittichai_chupol อ 14 ม.ค. 2020 3:19 pm บอร์ด PHP Knowledge
0
101
อ 14 ม.ค. 2020 3:19 pm โดย Ittichai_chupol
อยากทราบวิธีการแก้ไขปัญหา การเปิดใช้งาน xampp
โดย Ittichai_chupol อ 14 ม.ค. 2020 11:11 am บอร์ด Programming - PHP
6
2369
อ 14 ม.ค. 2020 3:20 pm โดย Ittichai_chupol
การแปลงข้อมูลที่ดึงมาจาก database ที่เป็น list ให้เป็น string เพื่อนำมาใช้ประโยชน์ในด้านต่างๆ
โดย benzas00123 จ 13 ม.ค. 2020 5:34 pm บอร์ด Python Knowledge
0
84
จ 13 ม.ค. 2020 5:34 pm โดย benzas00123
การใช้ os.walk ในการหานามสกุลไฟล์ที่ต้องการทั้งหมดที่อยู่ใน Project
โดย benzas00123 จ 13 ม.ค. 2020 3:09 pm บอร์ด Python Knowledge
0
98
จ 13 ม.ค. 2020 3:09 pm โดย benzas00123