Form và sự kiện trong react

Form và sự kiện trong react hướng dẫn bạn cách tạo form trong react và cách lấy các giá trị trong form khi làm web với React.

Chuẩn bị

1. Tạo project với lệnh create-react-app bai4

2.  Chuyển vào folder project và cài thư viện react-bootstrap

npm install react-bootstrap bootstrap@5.1.0

3. Trong file App.js. code lại:

import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import Container from 'react-bootstrap/Container';
import {  Col, Row } from "react-bootstrap";

function App() {
  return (
    <Container>
    <Row className="header bg-primary mb-1 text-white">HEADER </Row>    
    <Row>
        <Col sm={5} md={6} lg={7} style={{height:"350px"}} className="bg-warning p-2" id="tin1">
            Tin 1
        </Col>
        <Col sm={7} md={6} lg={5} className="p-0"> 
            <div id="tin2" style={{height:"175px"}} className="bg-info p-3"> Tin 2 </div>
            <div id="tin3" style={{height:"175px"}} className="bg-secondary p-3"> Tin 3 </div>
        </Col>
     </Row>
      <Row className="d-flex mt-2" style={{minHeight: "300px"}}>
          <Col sm={9} className="bg-info" id="maindata">  MAIN  </Col>
          <Col sm={3} className="bg-dark" id="ttbosung"> THÔNG TIN BỔ SUNG </Col>
      </Row>
    <Row className="footer my-1 bg-dark text-white" style={{minHeight: "120px"}}>
        <Col id="footer1" sm={6} className="bg-warning"> footer 1 </Col>
        <Col id="footer2" sm={3} className="bg-dark"> footer 2 </Col>
        <Col id="footer3" sm={3} className="bg-info"> footer 3</Col>
    </Row>
  </Container>   
  );
}
export default App;

4. File App.css, xóa hết code lại

.header {
  height: 60px; font-size: 2em;
  display: flex;  align-items: center;  justify-content: center;
}
.footer > div { display: flex; align-items: center; justify-content: center;}

5. Chạy trong trình duyệt, http://localhost:3000, kêt quả sẽ thế này

layput với boostrap react

Form trong React

Thêm form vào react giống như thêm các phần tử html bình thường. Nếu có dùng bootstrap, có thể dùng thêm các class mà bootstrap hỗ trợ để định dạng cho nhanh. Ví dụ sau tạo 1 form login

– Tạo file src/FormLogin.js

import React from 'react';
class FormLogin  extends React.Component{    
render(){
 const kq=
  <form className="p-1 text-white">
      <div className="mb-3">
        <label htmlFor="un">Tên đăng nhập</label>
        <input type="text" className="form-control" id="un"/>
      </div>
      <div className="mb-3">
        <label htmlFor="pass">Mật khẩu</label>
        <input type="password"  className="form-control" id="pass"/>
      </div>
      <button type="submit" className="btn btn-primary">Đăng nhập</button>
  </form>
  return (kq);
}
}
export default FormLogin;

– Trong App.js, import FormLogin:

import FormLogin from './FormLogin'; 

– Và cho FormLogin hiện ra trong layout

<Row className="d-flex mt-2" style={{minHeight: "300px"}}>
    <Col sm={9} className="bg-info" id="maindata">  MAIN  </Col>
    <Col sm={3} className="bg-dark" id="ttbosung"> 
      <FormLogin></FormLogin>
    </Col>
</Row>

Sự kiện trong form

Sự kiện onClick, onChange, onSubmit … diễn tả giống javascript nhưng nhớ ghi chữ hoa ngay tên chính của sự kiện.

Ví dụ: Xử lý sự kiện trong form login

import React from 'react';
class FormLogin  extends React.Component{   
getdata(e){
  console.log(e.target.id, e.target.value);
} 
render(){
 const kq=
  <form className="p-1 text-white">
      <div className="mb-3">
        <label htmlFor="un">Tên đăng nhập</label>
        <input type="text" onChange={this.getdata} className="form-control" id="un"/>
      </div>
      <div className="mb-3">
        <label htmlFor="pass">Mật khẩu</label>
        <input type="password" onChange={this.getdata} className="form-control" id="pass"/>
      </div>
      <button type="submit" className="btn btn-primary">Đăng nhập</button>
  </form>
  return (kq);
}
}
export default FormLogin;

Dùng this trong class component

Trong class component, this không được định nghĩa mặc định. Vì vậy trong các function thông thường, this không phải là “đối tượng này” . Ví dụ: trường hợp sau sẽ lỗi với từ this trong hàm layTuKhoa

– Tạo file  src/FormSearch.js

import React from 'react';
class FormSearch extends React.Component{
    constructor(){
        super();
        this.state = { url:"/action=search"}
    }
    layTuKhoa(e){
        let tk = e.target.value;
        let url = this.state.url;        
    }
    render(){
       const kq=
        <form className="p-2 border border-white text-center">
            <input onChange={this.layTuKhoa} placeholder="Từ khóa" className="form-control"/>
            <button type="button" className="btn btn-warning btn-sm mt-2">Tìm kiếm</button>
        </form>
        return (kq);
    }
}
export default FormSearch

– Import và cho hiện trong App.js

<Col sm={3} className="bg-dark" id="ttbosung"> 
  <FormLogin></FormLogin>
  <hr/>
  <FormSearch/>
</Col>

Kết quả: khi nhập từ khóa:

Dùng this trong arrow function

Dùng this trong các arrow function sẽ không bị lỗi. Trong arrow function this sẽ được hiểu là “đối tượng này”, tức là instance component hiện tại. Đó là cách thứ nhất để không bị lỗi khi dùng this.

import React from 'react';
class FormSearch extends React.Component{
    constructor(){
        super();
        this.state = { url:"/action=search"}
    }
    layTuKhoa = (e) => {
        let tk = e.target.value;
        let url = this.state.url;  
        console.log(tk, url);      
    }
    render(){
       const kq=
        <form className="p-2 border border-white text-center">
            <input onChange={this.layTuKhoa} placeholder="Từ khóa" className="form-control"/>
            <button type="button" className="btn btn-warning btn-sm mt-2">Tìm kiếm</button>
        </form>
        return (kq);
    }
}
export default FormSearch

Cách 2: nếu phải dùng function thông thường mà không dùng cho arrow function, thì phải liên kết this đến component instance bằng phương thức bind()

import React from 'react';
class FormSearch extends React.Component{
    constructor(){
        super();
        this.state = { url:"/action=search"};
        this.layTuKhoa = this.layTuKhoa.bind(this);
    }
    layTuKhoa(e) {
        let tk = e.target.value;
        let url = this.state.url;  
        console.log(tk, url);      
    }
    render(){
       const kq=
        <form className="p-2 border border-white text-center">
            <input onChange={this.layTuKhoa} placeholder="Từ khóa" className="form-control"/>
            <button type="button" className="btn btn-warning btn-sm mt-2">Tìm kiếm</button>
        </form>
        return (kq);
    }
}
export default FormSearch

Có 2 cách được sử dụng để truy cập giá trị của các phần tử trong form là Controlled Component và Uncontrolled Component

Uncontrolled Component

Uncontrolled input: giống như input HTML truyền thống, không cần viết hàm xử lý sự kiện cho mỗi lần cập nhật  giá trị trong input, mà tạo ref và gán ref cho tag . Nhờ đó sẽ có thể truy xuất giá trị của tag trong form.

Tạo ref bằng cách sử dụng hàm React.creacteRef trong constructor() và cho ref 1 tên. Ví dụ: this.hoten =  React.createRef();

Gán ref cho 1 tag HTML bằng cách dùng thuộc tính ref trong tag html. Ví dụ: ref={this.hoten}

Chú ý: trong component, khi truy cập đến ref (this.hoten.current) là đang tham chiếu đến cả tag html.

– Tạo src/FormLienHe.js

import React from 'react';
class FormLienHe extends React.Component{
constructor(){
    super();
    this.hoten =  React.createRef();
    this.tinh =  React.createRef();
    this.noidung =  React.createRef();
}
submitDuLieu = (e) =>{
    console.log(this.hoten.current.value);
    console.log(this.tinh.current.value);
    console.log(this.noidung.current.value);
    e.preventDefault();
}
render(){
    const kq = 
    <form className="p-2 col-9 m-auto text-white" onSubmit={this.submitDuLieu} >
        <div className="mb-3">
            <label htmlFor="ht">Họ tên </label>
            <input id="hoten" className="form-control bg-warning" 
            placeholder="Họ tên" ref={this.hoten} />
        </div>
        <div className="mb-3">
            <label htmlFor="ct">Tỉnh </label>
            <select id="tinh" className="form-control bg-warning" 
            placeholder="Chọn tỉnh" ref={this.tinh}> 
                <option value="0">Chọn tỉnh</option>
                <option value="1">Hà Nội</option>
                <option value="2">Hồ Chí Minh</option>
                <option value="3">Đà Nẵng</option>
            </select>
        </div>
        <div className="mb-3">
            <label htmlFor="noidung">Nội dung </label>
            <textarea id="noidung" className="form-control bg-warning" 
            placeholder="Nội dung liên hệ" ref={this.noidung}/>
        </div>
        <div className="mb-3">                
            <button className="btn btn-light">Gưi liên hệ</button>
        </div>
    </form>
    return (kq);
}
}
export default FormLienHe;

– Nhúng vào App.js:

import FormLienHe from './FormLienHe';

– Đưa form vào layout

 <Col sm={9} className="bg-info" id="maindata">  
     <FormLienHe/>
 </Col>

Controlled component

Controlled component liên kết giá trị trong tag với state, liện liên kết này  xử lý bằng cách tạo các hàm xử lý và gọi khi có sự thay đổi giá trị của tag. Ví dụ:

Ví dụ 2: Tạo src/FormLienHe2.js

import React from 'react';
class FormLienHe2 extends React.Component{
    constructor(){
        super();
        this.state ={hoten:'', tinh:0, noidung:''}
    }
    hoten = (e) => {
        this.state.hoten = e.target.value;
        console.log(this.state);
    }
    chontinh = (e) => {
        this.state.tinh = e.target.value;
        console.log(this.state);
    }
    noidung = (e) => {
        this.state.noidung = e.target.value;
        console.log(this.state);
    }
    submitDuLieu = (e) =>{
        console.log(this.state);
        e.preventDefault();
    }
    render(){
        const kq = 
        <form className="p-2 col-9 m-auto text-white" onSubmit={this.submitDuLieu} >
            <div className="mb-3">
                <label htmlFor="ht">Họ tên </label>
                <input id="hoten" className="form-control bg-warning" placeholder="Họ tên" onChange={this.hoten}/>
            </div>
            <div className="mb-3">
                <label htmlFor="ct">Tỉnh </label>
                <select id="tinh" className="form-control bg-warning" placeholder="Chọn tỉnh" onChange={this.chontinh}> 
                    <option value="0">Chọn tỉnh</option>
                    <option value="1">Hà Nội</option>
                    <option value="2">Hồ Chí Minh</option>
                    <option value="3">Đà Nẵng</option>
                </select>
            </div>
            <div className="mb-3">
                <label htmlFor="noidung">Nội dung </label>
                <textarea id="noidung" className="form-control bg-warning" placeholder="Nội dung liên hệ" onChange={this.noidung}/>
            </div>
            <div className="mb-3">                
                <button className="btn btn-light">Gưi liên hệ</button>
            </div>
        </form>
        return (kq);
    }
}
export default FormLienHe2;

– Nhúng vào App.js:

import FormLienHe2 from './FormLienHe2';

– Đưa form vào layout

 <Col sm={9} className="bg-info" id="maindata">  
     <FormLienHe2/>
 </Col>

Trên đây là các ví dụ về cách dùng Form và sự kiện trong react, cũng không khó phải không. Các bạn có thể tham khảo thẻm ở địa chỉ sau: https://www.w3schools.com/react/react_forms.asp .

Liên quan đến chủ đề Form và sự kiện trong react, các bạn đọc thêm bài này nữa nhé Sử dụng Redux form