หลังจากที่เราลองสร้าง class component และใช้งาน props มาในบทความก่อนหน้านี้ รอบนี้จะเป็นการใช้ handle event ของ form control และการ ใช้งาน state เบื้องต้น

state จะใช้ได้ใน class component เท่านั้น และ state สามารถเปลี่ยนแปลงแก้ไขค่าได้ อีกทั้งยังมี life cycle ของ class มาเกี่ยวข้อง ส่วน function component จะไม่มีการใช้ state

ซึ่งการใช้งาน state นั้นจะต้องถูกกำหนดค่าหรือ state เริ่มต้นที่ constructor ของ class component อีกทั้งยังต้องใช้คำสั่ง super ใน constructor อีกด้วยไม่นั้นจะ error ซึ่งเป็นข้อบังคับของทาง React.js

เอาละเรามาดูอย่างโค้ดกันเลยดีกว่าโดยผมจะตัดเอาโค้ดในส่วนที่อยู่ในส่วน tag script มานะครับ โดนเริ่มแรกผมจะทำการสร้าง method ทีมีชื่อว่า handleInputChange ใน ClassBasedCompont ตามโค้ดเลยครับ จากนั้นในส่วนของ render ให้เพิ่ม textbox ขึ้นมา 1 อันกำหนดชื่อว่า message จากนั้นกำหนด onChange ให้ทำการเรียกใช้งาน handleInputChange ตามโค้ดด้านล่างเลยครับ

**สามารถใช้โค้ดเก่าของบทความก่อนหน้า หรือ download code ได้ จาก Link นี้ครับ

   const containerElem = document.getElementById('root')

    class ClassBasedComponent extends React.Component{
      handleInputChange(){
        console.log('handelInputChange')
      }

      render(){
        return ( 
          <div>
            <h1>Class Based Component {this.props.firstname}</h1>
            <input type="text" name="message"  onChange={this.handleInputChange} />
          </div>
        )
      }
    }

    class App extends React.Component{
      render(){
        const firstname = 'Thaicoding'
        return(
          <div>
            <ClassBasedComponent firstname={firstname} />
          </div>
        )
      }
    }

    ReactDOM.render(<App />, containerElem)

เมื่อลองรันแล้วพิมพ์ข้อความใน textbox ก็จะเห็นว่ามีการเรียกใช้งาน handleInputChange

ที่นี้ลองแก้ handleInputChange ให้มี param event แล้วทำการ console.log ค่า event.target.name

      handleInputChange(event){
        console.log('handelInputChange')
        console.log(event.target.name)
        console.log(event.target.value)
      }

จะเห็นว่าเราสามารถอ้างอิงชื่อ control จาก event.target.name หรือถ้าเราต้องการค่า value ก็จะใช้คำสั่ง event.target.value

ที่นี้ผมลองสร้างตัวแปรขึ้นมาชื่อว่า message เพื่อทำการเก็บค่าข้อความและแสดงออกทางเพจ มีโค้ดตามด้านล่างครับ

    const containerElem = document.getElementById('root')
    let message = "Message"

    class ClassBasedComponent extends React.Component{
      handleInputChange(event){
        console.log('handelInputChange')
        console.log(event.target.name)
        console.log(event.target.value)
        message = event.target.value
      }

      render(){
        return ( 
          <div>
            <h1>Class Based Component {this.props.firstname}</h1>
            <p>{message}</p>
            <input type="text" name="message"  onChange={this.handleInputChange} />
          </div>
        )
      }
    }

    class App extends React.Component{
      render(){
        const firstname = 'Thaicoding'
        return(
          <div>
            <ClassBasedComponent firstname={firstname} />
          </div>
        )
      }
    }

    ReactDOM.render(<App />, containerElem)

เมื่อลอง run จะเห็นว่า ค่า message ไม่เปลี่ยน และนอกจากนั้นเราไม่สามารถประกาศตัวแปร message ใน ClassBasedComponent ได้

ลองสร้างตัวแปร message ใน ClassBasedComponent จะเกิด Error

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

        class ClassBasedComponent extends React.Component{
            constructor(){
                super()
                this.state = {
                    message:'Message'
                }
            }

            handleInputChange(event){
                console.log('handelInputChange')
                console.log(event.target.name)
                console.log(event.target.value)
            }

            render(){
                return ( 
                <div>
                    <h1>Class Based Component {this.props.firstname}</h1>
                    <p>{this.state.message}</p>
                    <input type="text" name="message"  onChange={this.handleInputChange} />
                </div>
                )
            }
        }

โค้ดใหม่ของ ClassBasedComponent มีการกำหนด state ที่ชื่อว่า message ขึ้นใน constructor และมีการ render ใน tag p ซึ่งในการอ้างค่าจะใช้ this.state.ชื่อ ซึ่งในโค้ดก็คือ this.state.message นั้นเอง

เมื่อลองรันโค้ดก็จะได้ดังรูป

ที่นี้ผมจะทำการเปลี่ยนค่า state message เมื่อค่า input text มีการเปลี่ยนแปลงซึ่งการกำหนดค่า state นั้นจะใช้คำสั่ง this.setState({ชื่อ state : ค่าที่ต้องการ}) ซึ่งผมทำการเปลี่ยนโค้ด method handleInputChange ตามโค้ดด้านล่างครับ

            handleInputChange(event){
                console.log('handelInputChange')
                console.log(event.target.name)
                console.log(event.target.value)
                this.setState({message:event.target.value})
            }

หลังจากลองรันผลก็คือ error ครับ เหตุผลเพราะ ES6 ใน React.Component นั้นจะไม่ทำการ auto bind method

หลังจาก พยายาม setState เกิด error เพราะ method ไม่ autobind

วิธีแก้มีอยู่หลายวิธี วิธีที่ 1 ทำการ bind method ใน constructor

            constructor(){
                super()
                this.state = {
                    message:'Message'
                }
                this.handleInputChange = this.handleInputChange.bind(this)
            }
        class ClassBasedComponent extends React.Component{
            constructor(){
                super()
                this.state = {
                    message:'Message'
                }
                this.handleInputChange = this.handleInputChange.bind(this)
            }

            handleInputChange(event){
                console.log('handelInputChange')
                console.log(event.target.name)
                console.log(event.target.value)
                this.setState({message:event.target.value})
            }

            render(){
                return ( 
                <div>
                    <h1>Class Based Component {this.props.firstname}</h1>
                    <p>{this.state.message}</p>
                    <input type="text" name="message"  onChange={this.handleInputChange} />
                </div>
                )
            }
        }

วิธีที่ 2. เปลี่ยน handleInputChange เป็น Arrow function

            handleInputChange = (event) =>{
                console.log('handelInputChange')
                console.log(event.target.name)
                console.log(event.target.value)
                this.setState({message:event.target.value})
            }
        class ClassBasedComponent extends React.Component{
            constructor(){
                super()
                this.state = {
                    message:'Message'
                }
            }

            handleInputChange = (event) =>{
                console.log('handelInputChange')
                console.log(event.target.name)
                console.log(event.target.value)
                this.setState({message:event.target.value})
            }

            render(){
                return ( 
                <div>
                    <h1>Class Based Component {this.props.firstname}</h1>
                    <p>{this.state.message}</p>
                    <input type="text" name="message"  onChange={this.handleInputChange} />
                </div>
                )
            }
        }

วิธีที่ 3. ตอนนี้ใช้งาน handleInputChange ให้เรียกแบบ Arrow Function

  <input type="text" name="message"  onChange={event => this.handleInputChange(event)} />
        class ClassBasedComponent extends React.Component{
            constructor(){
                super()
                this.state = {
                    message:'Message'
                }
            }

            handleInputChange(event){
                console.log('handelInputChange')
                console.log(event.target.name)
                console.log(event.target.value)
                this.setState({message:event.target.value})
            }

            render(){
                return ( 
                <div>
                    <h1>Class Based Component {this.props.firstname}</h1>
                    <p>{this.state.message}</p>
                    <input type="text" name="message"  onChange={event => this.handleInputChange(event)} />
                </div>
                )
            }
        }

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

Download Code

Leave a Reply

Your email address will not be published. Required fields are marked *