Ref in React

min read

Day 29/100 #100DaysOfCode #React

Hôm nay mình đi tìm hiểu về Ref trong React. Bởi vì mình thấy nhiều người đang sử dụng Ref để tương tác với các phần tử Dom HTML. Chúng ta thường thấy nhất Ref được đặt trong thẻ <input ref={this.email} /> đó là khi ta sử dụng function class compoment, còn trong hook để thì ta không cần this
Ok, mình sẽ tạo một project như sau : 

npx create-react-app react-ref
cd react-ref

Mọi người có thể tìm hiểu thêm tại đây : https://hoanguyenit.com/react

Đầu tiên mình mở scr/App.js xóa toạn bộ trong đó rồi viết lại theo ý mình thích vậy mà

import React, { Component } from 'react'
import './App.css';
/* use class component */
class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
       submit:false,
       _formData:{}
    }

     /* config */
    this.name = React.createRef();
    this.sex = React.createRef();
    this.address = React.createRef();

    /* set up btn submit form */
    this.sendInfo = this.sendInfo.bind(this)

  }

  render() {
    return (
       <>
	   
	   </>
    )
  }
}
export default App;

Trong đoạn code trên, mình khởi tạo trạng thái state, để bắt sự kiện form submit, đồng thời lưu thông tin dữ liệu vào _formData, còn function sendInfo chút mình chia sẻ bên dưới đây

this.state = {
       submit:false,
       _formData:{}
    }

Làm sao dùng được ref ta, vì thế ta mới có React.createRef(). Khi mà chúng ta đã có được ref, ta có thể đặt nó vào các thẻ element  của HTML, giúp ta có thể tham chiếu tới các  thẻ element trong HTML
Ví dụ ở bên trên tôi có nghiên cứu được cách tạo Ref như dưới đây. Chúng ta cần tạo cho từng biến (name,sex,address) thuộc ref

this.name = React.createRef();
    this.sex = React.createRef();
    this.address = React.createRef();

Để sử dụng được, ta sẽ tiến hành thêm nó vào các thẻ Element mà ta muốn, ví dụ như code dưới đây

<input type="text" name="name" ref={this.name} />
<select name="sex" ref={this.sex}>
    <option value="0">Nam</option>
    <option value="1">Nữ</option>
</select>
<input type="text" name="address" ref={this.address} />

Ta dùng ref={this.name} : ref nó sẽ lấy thông tin tại thẻ input hiện tại này, bạn có thể console.log(this.name) xem nó có gì nhé, xem ta có lấy được gì nửa không, mò nó xem nào
Còn muốn lấy value nhập tại thẻ input đó ta dụng như sau :

this.name.current.value

Bạn muốn trỏ con chuột tại vị trí input name thì dùng cách sau đây : Cách đặt vị trí focus này rất hay khi ta muốn chỉ người dùng đến element input mà ta cần

this.name.current.focus();

Còn nếu bạn muốn set value cho this.name ta có thể dụng như bên dưới : Cách này cũng thường dùng bởi vì, đôi khi ta muốn thay đổi giá trị hiện tại của nó.

Ví dụ :  bạn đang có một danh sách products nằm trong trang Home và tại trang Home Route link khi bấm vào sản phẩm product đó sẽ chuyển đến trang Detail. Mà trong Detail bạn có sản phẩm liên quan nửa mới căng. Vậy bạn làm cách nào khi bạn bấm vào sản phẩm trong Detail mà nó không Redirect tới Detail nửa. Nếu mà bạn cho nó redirect từ Detail/1 - > Detail/2 ->Detail/3 . Vậy chắc sẽ không ổn tí nào. Bạn thấy đó nó chỉ thay đổi ID của sản phẩm

Cho nên cách mà mình làm là sử dụng ref. Để cập nhật lại giá trị current của nó. Sao đó sử dụng các vòng đời component trong React Lifecycles , để call lại API, sao đó update lại dữ liệu tại đó, nói cách khác nó giống như AJAX load tại trang khi ta click vào sản phẩm nào đó vậy . Đó là cách mình đã dùng, chắc còn cách khác sẽ hay hơn, mà mình chưa làm tới. Để từ từ tìm hiểu tiếp vậy

this.name.current.value = "hoanguyenit.com";

Source code Demo : 

import React, { Component } from 'react'
import './App.css';

/* use class component */
class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
       submit:false,
       _formData:{}
    }

     /* config */
    this.name = React.createRef();
    this.sex = React.createRef();
    this.address = React.createRef();

    /* set up btn submit form */
    this.sendInfo = this.sendInfo.bind(this)

  }

  /* sendInfo function : request detail to backend  */
  sendInfo(e) {
      e.preventDefault();
      this.setState({submit:true});
      this.name.current.value="bac"
      let data = {
         _name:this.name.current.value,
         _sex:this.sex.current.value,
         _address:this.address.current.value
      }
      this.setState({_formData:data})
      /* request data to API Backend */
      /* 
        promise,
        axios,
        fetch
      */
  }

  render() {
    return (
      <div className="App">
        <form onSubmit={this.sendInfo}>
          <div className="form-box">
            <h1>Khai báo thông tin</h1>
            <div className="form-item">
              <label htmlFor="name">Họ và tên</label>
              <input type="text" name="name" ref={this.name} />
            </div>
            <div className="form-item">
              <label htmlFor="sex">Giới tính</label>
              <select name="sex" ref={this.sex}>
                 <option value="0">Nam</option>
                 <option value="1">Nữ</option>
              </select>
            </div>
            <div className="form-item">
              <label htmlFor="address">Địa chỉ</label>
              <input type="text" name="address" ref={this.address} />
            </div>
            <div className="form-item">
              <button type="submit" name="submit">Gửi Thông Tin</button>
            </div>
          </div>
         
        </form>
        {
              this.state.submit && <div style={{width:'400px',margin:'0 auto'}}>
                  <hr />
                  <label>Name : {this.name.current.value}</label>
                  <label>sex : {this.sex.current.value>0?"Nữ":"Nam"}</label>
                  <label>address : {this.address.current.value}</label>
              </div>
        }
        {
            this.state.submit && <div  style={{width:'400px',margin:'0 auto'}}>
                  {JSON.stringify(this.state._formData)}
              </div>
        }
      </div>
    )
  }
}
export default App;

Okay, mới hiểu được nhiêu đó, từ từ tìm hiểu tiếp, rồi cập nhật lại sau ::) . Kiến thức phong phú lắm, từ từ đi tìm nó, nó sẽ ở đó chờ ta tìm tới nó và trao cho ta một món quà! Dù ít hay nhiều nó cũng cho ta một thú vị nào đó, khó tả,....

x

Ủng hộ tôi bằng cách click vào quảng cáo. Để tôi có kinh phí tiếp tục phát triển Website!(Support me by clicking on the ad. Let me have the money to continue developing the Website!)