Hello, các chiến sĩ, này mình sẻ chia sẻ với mấy bạn về Restful API trong React. Thì Restful API tôi nghĩ các bạn đã sử dụng nhiều trong các dự án của bạn rồi, mình cũng có làm chia sẻ về vấn đề Restfull API rồi!
Nay mình sẽ thực hiện với một ví dụ đơn giản thôi!
Video demo:
Đầu tiên chúng ta tạo project thôi nào! Các bạn nào chưa biết tạo project thì hãy xem các bài viết trước nhé!
npx create-react-app restful-api cd restful-api npm install bootstrap@4.2.1 npm install react-router-dom npm install axios
Mấy thư viện trên mình đã có hướng dẫn về cách dùng ở những bài viết trước, phần này mình sẽ đi qua cho nhanh.
Sau khi tạo project xong, bạn cần import thư viện bootstrap vào index.js như sau:
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import * as serviceWorker from './serviceWorker'; import 'bootstrap/dist/css/bootstrap.css' ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') ); // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. // Learn more about service workers: https://bit.ly/CRA-PWA serviceWorker.unregister();
Để xử lý được Restful API bạn cần phải cài đặt thư viện Axios để xử lý chúng, cũng như trên đầu bài mình đã cài đặt, giờ ta chỉ cần thiết lập hàm gọi API thôi
Tạo file theo đường dẫn src/components/api/index.js
import axios from 'axios'; //mock API let API_URL = 'https://5adc8779b80f490014fb883a.mockapi.io'; export default function callApi(endpoint, method = 'GET', body) { return axios({ method, url: `${API_URL}/${endpoint}`, data: body }).catch(err => { console.log(err); }); }
Bạn có thể xem lại bài viết:Create CRUD in React trong bài này mình có sử dụng API
Ok, vậy là ta thiết lập gọi API xong, giờ ta chuẩn bị tạo component để call Restful API thôi
Tạo đường dẫn file src/components/admin/Product.js
import React, { Component } from 'react'; import {Link} from 'react-router-dom' import callApi from './api' export class Product extends Component { constructor(props){ super(props); this.state = { loading:false, _products:[] } } componentDidMount(){ callApi(`/products`,'GET',null).then(item=>{ console.log(item.data) //setState data this.setState({ loading:true, _products:item.data }) }); } deleteProduct = (id) => { callApi(`/products/${id}`,'DELETE',null).then((item)=>{ this.setState({ _products:this.state._products.filter(product=>product.id!=id) }) }) } render() { const {loading,_products} = this.state; if(!loading){ return( <h1>Loading...</h1> ) } return ( <div className="container"> <div className="row"> <div className="col-md-8"> <table className="table"> <thead> <tr> <th>ID</th> <th>Name</th> <th>Image</th> <th>Price</th> <th>Edit</th> <th>Delete</th> </tr> </thead> <tbody> { _products.map((item,index)=>( <tr key = {index}> <td>{item.id}</td> <td>{item.name}</td> <td><img src={item.image} style={{width:'60px',heightt:'40px'}} /></td> <td>{item.price}</td> <td><Link to={`/edit/${item.id}`}><span className="badge badge-warning text-white">modify</span></Link></td> <td><span className="badge badge-danger" onClick={()=>this.deleteProduct(item.id)}>remove</span></td> </tr> )) } </tbody> </table> </div> </div> </div> ) } } export default Product
Trong Product.js ta cần import đường dẫn api sau, để có thể gọi Restfull API
import callApi from './api'
Ta cần gọi thư viện react-router-dom trong component Product, để có thể sử dụng phần tử "Link"
import {Link} from 'react-router-dom'
Tạo dữ liệu State, dùng lưu trữ dữ liệu, sau đó chạy hàm callApi để nhận dữ liệu từ API
this.state = { loading:false, _products:[] } callApi(`/products`,'GET',null).then(item=>{ console.log(item.data) //setState data this.setState({ loading:true, _products:item.data }) });
Tạo hàm deleteProduct để xóa product,chúng ta dùng phương thức method="DELETE", kèm id trên URL route
deleteProduct = (id) => { callApi(`/products/${id}`,'DELETE',null).then((item)=>{ this.setState({ _products:this.state._products.filter(product=>product.id!=id) }) }) }
Cập nhật dữ liệu state lại sau khi xóa product
this.setState({ _products:this.state._products.filter(product=>product.id!=id) })
Tạo link trỏ tới component Edit
<Link to={`/edit/${item.id}`}><span className="badge badge-warning text-white">modify</span></Link>
Tạo file component đường dẫn src/components/admin/Post.js, dùng để thêm product
import React, { Component } from 'react' import callApi from './api' export class Post extends Component { constructor(props) { super(props) this.state = { name:"", price:"", image:"" } } postProduct = () => { let product = { name:this.state.name, image:this.state.image, price:parseInt(this.state.price) } callApi(`/products`,'POST',product).then((item)=>{ console.log(item) }); } render() { return ( <div className="container"> <div className="row"> <div className="col-md-8"> <h1>Post Product</h1> <div className="form-group"> <label>Name</label> <input type="text" className="form-control" value={this.state.name} onChange={(e)=>this.setState({name:e.target.value})}/> </div> <div className="form-group"> <label>Price</label> <input type="text" className="form-control" value={this.state.price} onChange={(e)=>this.setState({price:e.target.value})}/> </div> <div className="form-group"> <label>Image</label> <input type="text" className="form-control" value={this.state.image} onChange={(e)=>this.setState({image:e.target.value})}/> </div> <div className="form-group"> <button className="btn btn-primary" onClick={this.postProduct}>Update</button> </div> </div> </div> </div> ) } } export default Post
Trong component Post.js ta cần setup các State, lưu trữ dữ liệu
this.state = { name:"", price:"", image:"" }
Để thêm product được ta cần Restful API với method="POST"
postProduct = () => { let product = { name:this.state.name, image:this.state.image, price:parseInt(this.state.price) } callApi(`/products`,'POST',product).then((item)=>{ console.log(item) }); }
Chúng ta cần sử dụng phương thức onChange để cập nhật giá trị trạng thái
onChange={(e)=>this.setState({name:e.target.value})} onChange={(e)=>this.setState({price:e.target.value})}
Sử dụng phương thức onClick để gọi hàm postProduct
<button className="btn btn-primary" onClick={this.postProduct}>Update</button>
Tạo file component src/components/admin/Edit.js
import React, { Component } from 'react' import callApi from './api' export class Edit extends Component { constructor(props) { super(props) this.state = { id:0, name:"", price:"", } } componentDidMount(){ let id = this.props.match.params.id; callApi(`/products/${id}`,'GET',null).then((item)=>{ this.setState({ id:item.data.id, name:item.data.name, price:item.data.price }) }); } updateProduct = () => { let product = { name:this.state.name, price:parseInt(this.state.price) } callApi(`/products/${this.state.id}`,'PUT',product).then((item)=>{ console.log(item) }); } render() { return ( <div className="container"> <div className="row"> <div className="col-md-8"> <h1>Update Product</h1> <div className="form-group"> <label>Name</label> <input type="text" className="form-control" value={this.state.name} onChange={(e)=>this.setState({name:e.target.value})}/> </div> <div className="form-group"> <label>Price</label> <input type="text" className="form-control" value={this.state.price} onChange={(e)=>this.setState({price:e.target.value})}/> </div> <div className="form-group"> <button className="btn btn-primary" onClick={this.updateProduct}>Update</button> </div> </div> </div> </div> ) } } export default Edit
File Edit.js cũng giống như Post.js những trong component Edit.js ta cần phải nhận giá trị tham số từ URL route /edit/:id
let id = this.props.match.params.id;
Khi bạn đã nhận được id thì bạn có thể gọi Restful API với method="GET" để nhận thông tin về product hiện tại
callApi(`/products/${id}`,'GET',null).then((item)=>{ this.setState({ id:item.data.id, name:item.data.name, price:item.data.price }) });
Để cập nhật được giá trị hiện tại trên, ta cần tạo Restful API với method="PUT" để cập nhật lại giá trị product
updateProduct = () => { let product = { name:this.state.name, price:parseInt(this.state.price) } callApi(`/products/${this.state.id}`,'PUT',product).then((item)=>{ console.log(item) }); }
Ok vậy là xong, giờ để chạy được Route của từng component thì ta cần phải cài đặt cấu hình route trong file App.js
import React from 'react'; import './App.css'; import {BrowserRouter as Router,Link,Switch,Route} from 'react-router-dom' //import component import Product from './components/admin/Product' import Edit from './components/admin/Edit'; import Post from './components/admin/Post'; function App() { return ( <Router> <div className="container"> <Link to="/">List Products</Link> | <Link to="/post">Add Products</Link> </div> <Switch> <Route path="/" exact component={Product} /> <Route path="/post" component={Post} /> <Route path="/edit/:id?" component={Edit} /> </Switch> </Router> ); } export default App;
Nếu bạn chưa xem bài URL Router in React bạn có thể xem lại, cho dễ hình dung
Khởi động ứng dụng của ta thôi, xem nó chạy thế nào nhé!
npm start