Rest-based App React hướng dẫn bạn tạo ứng dụng để tương tác với API server nhằm quản lý data qua các thao tác xem, thêm sửa xóa dữ liệu. Ứng dụng react của bạn sẽ là phần front end tương tác với back end là các server API
Thiết lập api server
Api server là các server phục vụ các request từ xa qua http để cung cấp dữ liệu có cấu trúc cho client. Json-server là một thư viện nodeJS giúp bạn tạo API server đơn giản, đủ tính năng để dùng ở local.
Cài đặt json-server
npm install json-server
Xem tài liệu hướng dẫn dùng json server
Json-server hỗ trợ thêm record, cập nhật record, xóa record, lấy chi tiết 1 record, lấy danh sách record, sort, phân trang, filter… Xem tài liệu đầy đủ ở đây: https://www.npmjs.com/package/json-server
Tạo file dữ liệu cho json server
File database cho json-server là 1 file text. Chứa dữ liệu là mảng các object json. Mỗi mảng có 1 tên (loaisach, sach). Mời bạn tạo file text và lưu với tên sachHay.json , sau đó code:
{
"loaisach": [
{"id":"6","tenloai":"Nghệ thuật sống","thutu":"1","anhien":"1"},
{"id":"2","tenloai":"Lịch sử","thutu":"2","anhien":"1"},
{"id":"3","tenloai":"Thiếu nhi","thutu":"4","anhien":"1"}
],
"sach": [
{"id":"55","tensach":"Núi xanh nay vẫn đó","gia":"198000","urlHinh":"",
"idLoai":"2","xem":"535","hot":"0","moi":"0","mota":""},
{"id":"58","tensach":"Có 500 Năm Như Thế","gia":"124950","urlHinh":"",
"idLoai":"2","xem":"560","hot":"0","moi":"0","mota":""},
{"id":"105","tensach":"Sức Mạnh Của Sự Tử Tế","gia":"68000","urlHinh":"",
"idLoai":"6","xem":"751","hot":"0","moi":"0","mota":""}
],
"profile": {"ten": "sachHay","tacgia": "Nguyen Van Long" }
}
Chạy json-server
Mở command line, chuyển vào folder chứa file mới tạo và viết lệnh chạy json-server , truyền tham số là file database và giá trị port cho nó hoạt động:
json-server -w sachHay.json -p 3500
Test api server
Mở trình duyệt và gõ http://localhost:3500
Các chức năng json-server cung cấp qua API
Bảng sau mô tả các http method, đường dẫn và kết quả trả về của json- server đối với dữ liệu sách
Tạo project react để thực tập
- Tạo project mới để thực tập
- Chuyển vào project mới tạo và chạy npm start
- Mở index.html và nhúng bootstrap css vào
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
- Mở App.js và code tạo layout
import './App.css';
function App() {
return (
<div className="container">
<header className="row"> HEADER </header>
<main className="row">
<article className="col-sm-9 bg-info">
</article>
<aside className="col-sm-3 bg-secondary">
</aside>
</main>
</div>
);
}
export default App;
Định dạng trong App.css
header { background: darkcyan; height: 90px; position: relative;}
main { min-height: 500px;}
Xem kết quả:
Lấy danh sách các record trong từ API Server
Sau đây là cách để lấy danh sách record (loaisach): request đến api server với method GET và route là loaisach. Khi dữ liệu về, bạn gán vào state của component để dùng (hoặc có thể send lên store của redux)
a. Trong App.js, code nhúng component ListLoaiSach vào
b. Tạo component ListLoaiSach.js để hiện các loại sách
import React from "react";
class ListLoaiSach extends React.Component {
constructor(props){
super(props);
this.state = {listLoaiSach:null}
}
render() {
let kq= null;
return (kq);
};
};
export default ListLoaiSach;
c. Sau hàm constructor, định nghĩa làm lấy dữ liệu từ API về , lưu vào state listLoaiSach
componentDidMount(){
let url="http://localhost:3500/loaisach";
fetch(url).then(res => res.json()).then(data => {
this.setState({listLoaiSach:data});
});
}
d. Code lại hàm render để hiện dữ liệu
render() {
let kq= null;
if (this.state.listLoaiSach!==null)
kq= <div className="listLoaiSach">
{ this.state.listLoaiSach.map( loai =>(
<div className='MotLoaiSach' key={loai.id}>
<div>{loai.tenloai}</div>
<div>{loai.thutu}</div>
<div>{loai.anhien===1? "Đang hiện":"Đang ẩn"}</div>
<div className="button">
<button type='button' className='btn btn-sm btn-danger'> Xóa </button>
<button type='button' className='btn btn-sm btn-primary'> Sửa </button>
</div>
</div>
))
}
</div>
return (kq);
};
Định dạng trong App.css
.MotLoaiSach {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
grid-gap: 3px;
}
.MotLoaiSach >div { border: 0.5px solid black; padding: 3px 5px; margin-top: 3px; }
.MotLoaiSach >div:nth-child(2) { text-align:center;}
.MotLoaiSach >div:nth-child(3) { text-align:center;}
.MotLoaiSach >div:last-child{ text-align: right;}
Chạy trang sẽ thấy
Chức năng xóa 1 record
Để xóa 1 record loaisach, bạn request đến api server với method là DETETE route là loaisach/:id
a. Trong component ListLoaiSach, định nghĩa hàm xoaLoaiSach, sau khi xóa xong, nếu muốn cập nhật cách loại sách đang hiện thì thực hiện xóa record trong state:
xoaLoaiSach(id=1) {
let url=`http://localhost:3500/loaisach/${id}`;
fetch(url, {method:"DELETE"} ).then(res => res.json()).then(data => {
let arr = this.state.listLoaiSach.filter( s => {
if (s.id===id) return false; else return true;
})
this.setState({listLoaiSach:arr});
});
}
b. Code gọi hàm trong nút Xóa
onClick={()=>this.xoaLoaiSach(loai.id)}
Chức năng sửa 1 record
Để sửa 1 record loaisach, bạn request đến api server với method là PUT route là loaisach/:id và trong body request là chuỗi JSON của loại cần cập nhật
a. Trong component ListLoaiSach, định nghĩa hàm suaLoaiSach, hàm nhận id của loại cần sửa rồi record tương ứng để gửi ra ngoài component cha xử lý. Component cha sẽ render form sửa loai sách ra trang web.
suaLoaiSach(id=1) {
let index = this.state.listLoaiSach.findIndex( (ls) => { return ls.id===id})
let loaisach = this.state.listLoaiSach[index];
this.props.capnhat(loaisach)
}
b. Code gọi hàm trong nút Sửa
onClick={()=>this.suaLoaiSach(loai.id)}
Mỗi khi nhắp núit Sửa, hàm suaLoaiSach chạy, hàm này gọi hàm capnhat của component cha. Hàm capnhat ngoài component cha sẽ render form sửa loại sách cho bạn. Hãy test bằng cch nhắp nút Sửa, bạn sẽ thấy báo lỗi tại lệnh this.props.capnhat do chưa định nghĩa hàm này.
c. Định nghĩa props capnhat trong App.js + hàm updateLoaiSach + vị trí hiện form sửa loại sách.
d. Tạo component SuaLoaiSach
import React from "react";
class SuaLoaiSach extends React.Component {
constructor(props){ super();
this.state = {loaisach:{} }
this.tenloai = React.createRef();
this.thutu = React.createRef();
this.anhien = React.createRef();
}
render() {
return (
<div className="suaLoaiSach m-2">
<div className="mb-3">
<input className="form-control" placeholder="Tên loại sách"
ref={this.tenloai} defaultValue={this.props.loaisach.tenloai} />
</div>
<div className="mb-3">
<input className="form-control" placeholder="Thứ tự"
ref={this.thutu} defaultValue={this.props.loaisach.thutu}/>
</div>
<div className="mb-3">
<input className="form-control" placeholder="Ẩn hiện"
ref={this.anhien} defaultValue={this.props.loaisach.anhien}/>
</div>
<div className="mb-3">
<button type="button" className="btn btn-primary" >
Sửa Loại Sách
</button>
</div>
</div>
)}
};
export default SuaLoaiSach;
e. Định nghĩa hàm hamSuaLoaiSach
Code trong component SuaLoaiSach:
hamSuaLoaiSach = () => {
let loaisach = {
id: this.props.loaisach.id,
tenloai: this.tenloai.current.value,
thutu: this.thutu.current.value,
anhien: this.anhien.current.value,
}
let idLoaiSach = this.props.loaisach.id;
let url=`http://localhost:3500/loaisach/${idLoaiSach}`;
fetch(url, { method:"PUT",
body:JSON.stringify(loaisach),
headers:{'Content-Type':'application/json'}
}
)
.then(res => res.json())
.then( d => console.log("Đã cập nhật xong", d));
}
f. Code gọi hàm trong nút Sửa Loại Sách
onClick={this.hamSuaLoaiSach}
Test: chạy project: nhắp nút Sửa, sẽ thấy form Sửa loại sách. Nhập giá trị mới trong form rồi nhắp nút Sửa Loại Sách, sẽ cập nhật lên API Server. Bạn nạp lại trang web sẽ thấy thay đổi.
Chức năng thêm 1 record trong rest-based app react
Để thêm 1 record loaisach, bạn request đến api server với method là POST route là loaisach/:id và trong body request là chuỗi JSON của loại cần thêm
a. Tạo component ThemLoaiSach , giống như component SuaLoaiSach, nhưng không cần defaultValue cho các input, idLoaiSach bạn có thể cho user nhập trong form hoặc tự phát sinh.
b. Cho hiện component ra layout: bạn có thể cho hiện ở đâu tùy ý, có thể cho hiện khi nhắp nút Thêm loại thì tốt
c. Khi nhắp nút Thêm trong form, code để gọi API như hình trên
Mời bạn thực hiện thêm
- Mỗi lần cập nhật loại sách hoặc thêm loại sách thì cho render lại component list loại sách để thấy ngay kết quả cập nhật
- Thêm title cho các field trong component list loại sách
- Thực hiện chức năng xem chi tiết 1 record
- Có thế áp dụng thêm redux nếu muốn.
- Áp dụng sort, phân trang trong component list loại sách