REACTJS EXAMPLE
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Tạo ứng dụng ghi chú với ReactJS và Redux

Trong bài viết này mình sẽ hướng dẫn xây dựng một ứng dụng ghi chú đơn giản sử dụng ReactJS và Redux. Đây cũng là một project nhỏ giúp làm quen với Redux.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Bạn cần chuẩn bị một vài kiến thức về Redux trước khi bắt tay vào xây dựng ứng dụng bằng cách tham khảo bài viết về tích hợp Redux vào ReactJS.

Ở đây ta sẽ xây dựng ứng dụng ghi chú đơn giản với chức năng bao gồm thêm, sửa, xóa ghi chú, có cấu trúc thư mục src như sau:

src/
....const/
        index.js
.....actions/
        index.js
....reducers/
        noteReducer.js
        index.js
----components/
       AddNote.css
       AddNote.js
       ShowNote.js
....App.js

Ngoài ra mình có sử dụng thư viện Bootstrap 4 để xây dựng giao diện, hãy tham khảo thêm về Bootstrap 4 để có thể hiểu rõ hơn nhé.

Bài viết này được đăng tại [free tuts .net]

ung dung ghi chu react js JPG
Giao diện của ứng dụng ghi chú

1. Cài đặt thư viện cần thiết

Trước tiên cần phải cài đặt redux cho dự án của mình bằng npm với câu lệnh:

npm install redux react-redux --save

Để có thể xây dựng giao diện dễ dàng hơn ta sẽ sử dụng Bootstrap 4, tiến hành thêm thư viện bootstrap vào bên trong thẻ <head> của file public/index.html.

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">

Bước tiếp theo phải phân tích xem project cần những chức năng gì, để từ đó xây dựng cấu trúc redux một cách hợp lí hơn. Đối với project này bao gồm 3 chức năng chính đó là thêm, sửa, xóa ghi chú. Đồng nghĩa với đó là sẽ có 3 actions, 1 reducers và 3 const,..chúng ta sẽ triển khai ở bên dưới.

2. Triển khai Redux

Chúng ta sẽ triển khai mô hình Redux với 3 thư mục đó là actions, reducers, const,..Với từng thư mục sẽ có chức năng riêng.

Thư mục const sẽ chứa các hằng số hỗ trợ trong quá trình triển khai dự án. Ta sẽ khai báo các hằng số ở trong file const/index.js.

// const/index.js
export const ADD_NEW_NOTE = "ADD_NEW_NOTE";
export const REMOVE_NOTE = "REMOVE_NOTE";
export const EDIT_NOTE = "EDIT_NOTE";

Thư mục actions sẽ bao gồm các hàm chứa hành động để thực hiện dispatch tới reducers. Ở đây chúng ta sẽ triển khai các hàm ở file actions/index.js.

import { ADD_NEW_NOTE, REMOVE_NOTE, EDIT_NOTE } from "../const/index";
//action thêm note
export const actAddNote = (content) => {
  return {
    type: ADD_NEW_NOTE,
    content,
  };
};
//Xóa note
export const actRemoveNote = (id) => {
  return {
    type: REMOVE_NOTE,
    id,
  };
};
//Sửa note
export const actEditNote = (id, content) => {
  return {
    type: EDIT_NOTE,
    id,
    content,
  };
};

Có 3 hàm được export ở file actions/index.js đó là actAddNote, actRemoveNote, actEditNote dùng để tạo action cho chức năng thêm, sửa, xóa note.

Thư mục reducers sẽ chứa các hàm chứa các reducers trong Redux, có 2 files đó là

  • noteReducers.js : reducers hỗ trợ thực thi hành động với ghi chú như thêm, sửa, xóa. Ta có thể tạo nhiều reducers như này, và gộp nó vào bằng phương thức combineReducers trong redux.
  • index.js : trong trường hợp có nhiều reducers thì gộp tất cả reducers ở đây.
//reducesr/noteReducers.js

//Import các const
import { ADD_NEW_NOTE, REMOVE_NOTE, EDIT_NOTE } from "../const/index";

const noteReducers = (state = [], action) => {
  switch (action.type) {
    case ADD_NEW_NOTE:
      const generateID = new Date().getTime();
      state = [...state, { id: generateID, content: action.content }];
      return state;

    case EDIT_NOTE:
      const indexOfEditNote = state.findIndex((note) => note.id === action.id);
      if (indexOfEditNote !== -1)
        state[indexOfEditNote].content = action.content;
     
      return state;

    case REMOVE_NOTE:
      const idRemove = action.id;
      state = state.filter(note => {
        if (note.id === idRemove) 
          return false
        return true
      })
      return state;
    default:
      return state;
  }
};

export default noteReducers
//reducers/index.js
import {combineReducers} from 'redux'
import noteReducers from './noteReducer'

export default combineReducers({
    note: noteReducers
})

Để các component khác có thể tương tác với Store ta cần bọc root component bởi Provider. Ở file src/index.js sẽ chỉnh sửa lại như sau.

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";

import { Provider } from "react-redux";
import { createStore } from "redux";

//Gọi reducers
import reducers from "./reducers/index";


//Tạo store từ reducers
const store = createStore(reducers);

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>,
  document.getElementById("root")
);

serviceWorker.unregister();

Vậy là các bước cài đặt redux xong, tiếp theo sẽ là đi xây dựng các component.

3. Xây dựng giao diện ứng dụng ghi chú

Bây giờ sẽ đi xây dựng giao diện và kết nối với store redux trong mỗi component. Ví dụ này sẽ có 2 components đó thêm và hiển thị ghi chú (nằm trong thư mục src/components).

Ở đây 2 component AddNoteShowNote sẽ được render ở trong file src/App.js

//file: src/App.js
import React from "react";
import "./App.css";
//Kết nối vơi redux
import { connect } from "react-redux";
import ShowNote from './components/ShowNote'
import AddNote from './components/AddNote'
function App(props) {
  return (
    <div className="row" style={{ marginTop: "3%" }}>
      <AddNote />
      {props.note.map((note, index) => {
          // Render ra lần lượt các ghi chú.
          return <ShowNote noteData = {note} key={note.id}/>
      })}
    </div>
  );
}

// Lấy state từ store bằng mapStateToProps
// Lúc này state nhận được sẽ gán vào props
const mapStateToProps = (state, ownProps) => {
  // Gán state nhận về từ store 
  // thành props có tên note (props.note)
  return {
    note: state.note,
  };
};

export default connect(mapStateToProps, null)(App);

Component AddNote sẽ có chức năng thêm ghi chú mới, file AddNote.js sẽ có nội dung như sau:

//file AddNote.js

import React, { useState, useRef } from "react";
import { connect } from "react-redux";
//Import actions vào đây
import { actAddNote } from "../actions/index";

function AddNote(props) {
  const [content, setContent] = useState();

  //Refs: Giúp chúng ta tương tác với DOM thật

  const noteInput = useRef(null)

  //Khi click vào nút thêm sẽ gọi hàm này,
  const handleAdd = () => {

    // Dispatch action.
    // Props này được tạo bởi hàm
    // mapDispatchToProps bên dưới
    props.addNote(content)

    //Gán giá trị cho input thành rỗng
    noteInput.current.value = ''

    //Cập nhật lại state content
    setContent('')
  };
  
  return (
    <div className="col-md-12" style={{ marginBottom: 15 }}>
      <div className="input-group mb-8">
        <input
          type="text"
          className="form-control"
          placeholder="Nội dung ghi chú"
          value =  {content}
          onChange={(e) => {
            setContent(e.target.value)
          }}
          ref={noteInput}
        />
        <div className="input-group-append">
          <button className="btn btn-primary" onClick={handleAdd}>
            Thêm
          </button>
        </div>
      </div>
    </div>
  );
}

//Chuyển dispatch thành props.
//Ở đây nếu mình muốn dispatch action actAddNote
//thì chỉ cần gọi props.addNote(content)
const mapDispatchToProps = (dispatch) => {
  return {
    addNote: (content) => {
      dispatch(actAddNote(content));
    },
  };
};
export default connect(null, mapDispatchToProps)(AddNote);

Component ShowNote sẽ nhận vào một props là dataNote chứ các thuộc tính của từng ghi chú. Component này sẽ có chức năng sửa và xóa các ghi chú.

//file: src/components/ShowNote.js
import React, { useState } from "react";
import "./ShowNote.css";
import { connect } from "react-redux";
import { actEditNote, actRemoveNote } from "../actions/index";

function ShowNote(props) {
  const [noteContent, setNoteContent] = useState(props.noteData.content)

  //Lấy ID của ghi chú 
  const noteID = props.noteData.id


  // Được gọi mỗi khi thay đổi giá trị
  // của ghi chú.
  const handleChange = (e) => {
    setNoteContent(e.target.value)
    props.editNote(noteID, e.target.value)
  }

  //Được gọi khi click vào 
  //xóa ghi chú.
  const handleRemoveNote = () => {
    props.removeNote(noteID)
  }
  return (
    <div className="col-md-4" style={{marginTop: 10}}>
      <div className="card bg-warning">
        <div className="card-body" style={{ height: 200 }}>
          <textarea value= {noteContent} onChange = {handleChange}></textarea>
        </div>
        <div className="card-footer">
          <button className="btn btn-danger btn-sm float-right" onClick={handleRemoveNote}>Xóa</button>
        </div>
      </div>
    </div>
  );
}

// chuyển dispatch thành props
const mapDispatchToProps = (dispatch) => {
  return {
    editNote: (id, content) => {
      dispatch(actEditNote(id, content));
    },
    removeNote: id => {
      dispatch(actRemoveNote(id));
    }
  };
};

// chuyển state từ store thành props
// của component
const mapStateToProps = (state, ownProps) => {
  return {
    note: state.note,
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(ShowNote);

Để giao diện của component ShowNote đẹp hơn 1 chút thì ta sẽ thêm một vài đoạn css ở file ShowNote.css

/* src/components/ShowNote.css */
textarea {
    background-color: rgba(0, 0, 0, 0);
    border-width: 0;
    overflow: hidden;
    resize: none;
}
textarea:focus{
    outline: none;
}

Đây cũng là buớc cuối cùng để xây dựng ứng dụng ghi chú, để khởi chạy dự án ta chỉ cần mở terminal và gõ dòng lệnh:

npm start

Trên đây là ví dụ về khởi tạo ứng dụng ghi chú sử dụng ReactJS và Redux, mong rằng ví dụ này sẽ giúp bạn có thể nắm chắc hơn về cách triển khai redux trong một dự án thực tế.

Danh sách file tải về

Tên file tải về Pass giải nén
Ứng dụng Ghi chú ReactJS freetuts.net hoặc gameportable.net

Cùng chuyên mục:

Bài tập ReactJS: API Requests trong ReactJS

Bài tập ReactJS: API Requests trong ReactJS

Bài tập ReactJS: Conditional Rendering trong ReactJS

Bài tập ReactJS: Conditional Rendering trong ReactJS

Bài tập ReactJS: Lists và Keys trong ReactJS

Bài tập ReactJS: Lists và Keys trong ReactJS

Bài tập ReactJS: Forms và Controlled Components trong ReactJS

Bài tập ReactJS: Forms và Controlled Components trong ReactJS

Bài tập ReactJS: Handling Events trong ReactJS

Bài tập ReactJS: Handling Events trong ReactJS

Bài tập ReactJS: State và Lifecycle trong ReactJS

Bài tập ReactJS: State và Lifecycle trong ReactJS

Bài tập ReactJS: Components và Props trong ReactJS

Bài tập ReactJS: Components và Props trong ReactJS

Thiết kế và quản lý form đơn giản với thư viện Formik

Thiết kế và quản lý form đơn giản với thư viện Formik

React Microservices, xây dựng ứng dụng React mạnh mẽ

React Microservices, xây dựng ứng dụng React mạnh mẽ

Xây dựng ứng dụng CRUD với Redux Toolkit cực dễ dàng

Xây dựng ứng dụng CRUD với Redux Toolkit cực dễ dàng

Áp dụng Testing vào React cho ứng dụng của bạn như thế nào?

Áp dụng Testing vào React cho ứng dụng của bạn như thế nào?

Performance Optimization trong React Js, tăng hiệu suất cực ngon

Performance Optimization trong React Js, tăng hiệu suất cực ngon

React Hook là gì? Tại sao React Hook quan trọng trong dự án?

React Hook là gì? Tại sao React Hook quan trọng trong dự án?

Hiểu Route React nâng cao trong 10 phút bằng ví dụ

Hiểu Route React nâng cao trong 10 phút bằng ví dụ

Xây dựng Hook trong React JS (React Custom Hook)

Xây dựng Hook trong React JS (React Custom Hook)

React Hooks là một tính năng mới trong React 16.8. Cho phép sử dụng state…

Cách đẩy ứng dụng ReactJS lên Heroku và Deploy trên đó

Cách đẩy ứng dụng ReactJS lên Heroku và Deploy trên đó

Cho bạn nào chưa bíết thì Heroku mà môt nền tảng đám mây hỗ trợ…

Tích hợp Redux vào ReactJS

Tích hợp Redux vào ReactJS

Trong bài viết này chúng ta sẽ cùng nhau đi tìm hiểu về cách tích…

Tạo máy tính đơn giản bằng ReactJS

Tạo máy tính đơn giản bằng ReactJS

Trong bài này ta sẽ xây dựng một ứng dụng máy tính đơn giản bằng…

Redux là gì? Tại sao lại ứng dụng trong ReactJS

Redux là gì? Tại sao lại ứng dụng trong ReactJS

Trong bài viết này chúng ta sẽ cùng nhau đi tìm hiểu về Redux trong…

useContext trong React Hook

useContext trong React Hook

Trong bài viết này chúng ta sẽ cùnuseContextg nhau đi tìm hiểu về useContext trong…

Top