Restful API using React

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 

Bài Viết Liên Quan

Messsage

Nếu bạn thích chia sẻ của tôi, đừng quên nhấn nút !ĐĂNG KÝ