React.js xử lý delete

React.js xử lý delete

Tạo button xóa dữ liệu

  • Trước tiên ta cần tạo button bên trong file /client/src/App.js như sau:
<ul>
  {this.state.news.map(item => (
    <li key={item.id}>
      <h2>{item.title}</h2>
      <div>{item.description}</div>
        <button onClick={() => this.openModal(item)}>Edit</button>
        <button onClick={() => this.handleDelete(item)}>Delete</button>
    </li>
  ))}
</ul>
  • handleDelete - là function xử lý xóa dữ liệu.
  • Thuộc tính bind - dùng để sử dụng phương thức this, nhằm xác định rõ button nào được click.

Kết quả

React.js MySQL delete

  • Ta tạo function xử lý button, sao cho khi click vào button sẽ lấy được id của mục có button được click, ta thực hiện như sau:
handleDelete = (item) => {
  const newsId = item.id;
  console.log(newsId);
}
  • Khi này khi click button và xem console.log (Chrome nhấn F12, chọn Console) thì các bạn sẽ thấy id của item chứa button xuất hiện.

Xử lý xóa dữ liệu ở phía client

  • Tiếp theo ta sẽ viết lại function handleDelete sao cho có thể xóa được item nào chứa button được click, ta viết như sau:
handleDelete = (item) => {
  const newsId = item.id;
  this.setState(prevState => ({
    news: prevState.news.filter(elm => elm.id !== newsId )
  }));
}
  • filter(elm => elm.id !== newsId ), đây là bộ lọc mãng trong Javascript, sẽ lọc tất cả item nào có id khác với newsId (với newsIdid của item có button được click), khi này ta sẽ lấy tất cả item ngoại trừ item có newsId.
  • Giờ thì các bạn thử click bất kỳ button nào sẽ thấy item tương ứng sẽ bị xóa, kết quả dưới đây là sau khi xóa item với "Tiêu đề MỚI NHẤT".

React.js MySQL delete

  • Tuy nhiên, sau khi reload lại trình duyệt thì item vừa xóa sẽ xuất hiện trở lại, lý do là ta chỉ xóa ở phía client thôi, dữ liệu ở phía server vẫn còn, do đó ta cần xóa luôn dữ liệu ở phía server nữa, xem tiếp bên dưới nhé.

Xử lý xóa dữ liệu MySQL

  • Tiếp theo ta cần xử lý sao cho khi click button sẽ tiến hành xóa dữ liệu ở phía client, và đồng thời cũng xóa dữ liệu ở MySQL.
  • Ta lần lượt chỉnh lại nội dung /client/src/App.js/app.js như sau:

/client/src/App.js

handleDelete = (item) => {
  const newsId = {
    id: item.id
  };

  axios.post('/api/delete', newsId)
  .then(res => {
    this.setState(prevState => ({
      news: prevState.news.filter(el => el.id !== item.id )
    }));
  })
  .catch(error => console.log(error));
}
  • Vì dữ liệu gửi đi có dạng Object, do đó ta cần viết lại newsId dưới dạng Object.
  • axios.post Chúng ta sẽ sử dụng Axios để gửi dữ liệu.
  • ('/api/delete', newsId) dữ liệu sẽ được gửi thông qua route.
  • Bên trong vẫn là hàm xử lý xóa dữ liệu ở client, để đảm bảo dữ liệu được gửi mới tiến hành xóa dữ liệu.

/app.js

app.post('/api/delete', (req, res) => {
  var sql = "DELETE FROM news "
          + "WHERE id='"+req.body.id+"'";
  connection.query(sql, function(err, results) {
    if (err) throw err;
    res.json({news: results});
  });
});
  • Nếu bạn đã quen với bài học insert và update rồi, thì nội dung trên sẽ không lạ, nên mình không cần giải thích thêm nhé.
  • Để chạy được kết quả, chúng ta cần npm run dev lại là được.
  • Tới đây ta đã hoàn thành việc xóa dữ liệu ở phía client và server rồi, giờ các bạn có thể test lại kết quả nhé.

Tổng kết

  • Sau khi hoàn nội dung bài học, ta sẽ tạo được 2 file /client/src/App.js/app.js như sau:

/client/src/App.js

Code bao gồm phần insert và update.

import React, { Component } from 'react';
import axios from 'axios';
import Modal from 'react-modal';

class App extends Component {
  constructor (props) {
    super(props);
    this.state = {
      modalIsOpen: false,
      news: [],
      id: '',
      title: '',
      description: '',
      content: ''
    }
  };

  componentDidMount() {
    axios.get('/api/news')
         .then(res => {
            const news = res.data;
            this.setState({ news: news.news });
          })
         .catch(error => console.log(error));
  };

  handleInputChange = (event) => {
    const target = event.target;
    const value = target.value;
    const name = target.name;
    this.setState({
      [name]: value
    });
  };

  handleInsertSubmit = (event) => {
    event.preventDefault();

    const newItem = {
        id: '',
        title: this.state.title,
        description: this.state.description,
        content: this.state.content
    };

    axios.post('/api/insert', newItem)
      .then(res => {
        let news = this.state.news;
        news = [newItem,...news];
        this.setState({ news: news });
      })
      .catch(error => console.log(error));
  };

  componentWillMount() {
    Modal.setAppElement('body');
  };

  openModal = (item) => {
    this.setState({
      modalIsOpen: true,
      id: item.id,
      title: item.title,
      description: item.description,
      content: item.content
    });
  };

  closeModal = () => {
    this.setState({
      modalIsOpen: false
    });
  };

  handleEditSubmit = (event) => {
    event.preventDefault();

    const newUpdate = {
      id: this.state.id,
      title: this.state.title,
      description: this.state.description,
      content: this.state.content
    };

    axios.post('/api/edit', newUpdate)
    .then(res => {
      let key = this.state.id;
      this.setState(prevState => ({
        news: prevState.news.map(
          elm => elm.id === key? {
            ...elm,
            title: this.state.title,
            description: this.state.description,
            content: this.state.content
          }: elm
        )
      }))
    })
    .catch(error => console.log(error));
  };

  handleDelete = (item) => {
    const newsId = {
        id: item.id
    };

    axios.post('/api/delete', newsId)
    .then(res => {
      this.setState(prevState => ({
        news: prevState.news.filter(el => el.id !== item.id )
      }));
    })
    .catch(error => console.log(error));
  };

  render() {
    return(
      <div>
        <h2>Add an item</h2>
        <form onSubmit={this.handleInsertSubmit}>
          <table>
            <tbody>
              <tr>
                <th><label>Title</label></th>
                <td>
                  <input
                    name="title"
                    type="text"
                    onChange={this.handleInputChange} />
                </td>
              </tr>

              <tr>
                <th><label>Description</label></th>
                <td>
                  <textarea
                    name="description"
                    onChange={this.handleInputChange} />
                </td>
              </tr>

              <tr>
                <th><label>Content</label></th>
                <td>
                  <textarea
                    name="content"
                    onChange={this.handleInputChange} />
                </td>
              </tr>
            </tbody>
          </table>

          <button type="submit">Submit</button>
        </form>

        <hr />

        <ul>
          {this.state.news.map(item => (
            <li key={item.id}>
              <h2>{item.title}</h2>
              <div>{item.description}</div>
               <button onClick={() => this.openModal(item)}>Edit</button>
               <button onClick={() => this.handleDelete(item)}>Delete</button>
            </li>
          ))}
        </ul>

        <Modal
          isOpen={this.state.modalIsOpen}
          onRequestClose={this.closeModal}>
          <button onClick={this.closeModal}>Close</button>
          <form onSubmit={this.handleEditSubmit}>
            <table>
              <tbody>
                <tr>
                  <th><label>Title</label></th>
                  <td>
                    <input
                      type="text"
                      name="title"
                      value={this.state.title} 
                      onChange={this.handleInputChange} />
                  </td>
                </tr>

                <tr>
                  <th><label>Description</label></th>
                  <td>
                    <textarea
                      name="description"
                      value={this.state.description} 
                      onChange={this.handleInputChange} />
                  </td>
                </tr>

                <tr>
                  <th><label>Content</label></th>
                  <td>
                    <textarea
                      name="content"
                      value={this.state.content} 
                      onChange={this.handleInputChange} />
                  </td>
                </tr>
              </tbody>
            </table>
            <button type="submit">Edit</button>
          </form>
        </Modal>
      </div>
    )
  }
};

export default App;

/app.js

const express = require('express');
const mysql = require('mysql');
const app = express();
const bodyParser = require('body-parser');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));

const connection = mysql.createConnection({
  host: 'localhost',
  user: 'reactUser',
  password: '1234567',
  database: 'reactmysql'
});

connection.connect(function(err){
  (err) ? console.log(err) : console.log(connection);
});

app.get('/api/news', (req, res) => {
  var sql = "SELECT * FROM news ORDER BY id DESC";
  connection.query(sql, function(err, results) {
    if (err) throw err;
    res.json({news: results});
  });
});

app.post('/api/insert', function(req, res) {
  var sql = "INSERT "
          + "INTO news(title,description,content) "
          + "VALUES('"
          +   req.body.title+ "','" 
          +   req.body.description + "','" 
          +   req.body.content+"')";
  connection.query(sql, function (err, results) {
    if(err) throw err;
    res.json({news: results});
  });
});

app.post('/api/edit', (req, res) => {
  var sql = "UPDATE news SET "
          +   "title='"+req.body.title+"',"
          +   "description='"+req.body.description+"',"
          +   "content='"+req.body.content+"'"
          + "WHERE id='"+req.body.id+"'";
  connection.query(sql, function(err, results) {
    if (err) throw err;
    res.json({news: results});
  });
});

app.post('/api/delete', (req, res) => {
  var sql = "DELETE FROM news "
          + "WHERE id='"+req.body.id+"'";
  connection.query(sql, function(err, results) {
    if (err) throw err;
    res.json({news: results});
  });
});
 
app.listen(4000, () => console.log('App listening on port 4000'));
  • Tới đây ta đã hoàn thành bài học về xóa dữ liệu, các bạn có thể kết hợp các bài insert, update, delete để làm nền tảng cho ứng dụng của mình được rồi.
  • Toàn bộ bài học từ View, insert, update, delete các bạn download tại ReactMySQL-View-Insert-Update-Delete nhé, cài đặt y như hướng dẫn là được.