Thông tin liên hệ
- 036.686.3943
- admin@nguoicodonvn2008.info
Khi quản lý trạng thái phức tạp trong app Next, mọi thứ có thể trở nên khó khăn. Tuy nhiên, bạn có thể khắc phục bằng cách tìm hiểu nguyên tắc cơ bản của React và quản lý trạng thái qua ứng dụng kinh điển này.

Trước khi bắt đầu làm app liệt kê việc cần làm, bạn phải chuẩn bị:
Trạng thái ứng dụng chỉ điều kiện của app hiện tại ở một thời điểm nhất định, bao gồm thông tin & quản lý app, như input người dùng và tìm nạp dữ liệu từ database hoặc một API (Application Programming Interface).
Để hiểu trạng thái ứng dụng, hãy cân nhắc các trường hợp có thể của một app bộ đếm đơn giản, bao gồm:
Một thành phần React có thể đăng ký thay đổi trạng thái. Khi người dùng tương tác với một thành phần như thế, những tác vụ như click nút bấm có thể update trạng thái này.
Đoạn code dưới hiện một ứng dụng bộ đếm đơn giản, ở trạng thái mặc định, được dùng để quản lý trạng thái các tác vụ click:
const [counter, setCounter] = useState(0);
return (
<main>
<h1>{counter}</h1>
<button onClick={() => setCounter(counter + 1)}>increase</button>
<button onClick={() => setCounter(counter - 1)}>decrease</button>
<button onClick={() => setCounter(0)}>reset</button>
</main>
);
Repository của dự án chứa hai nhánh: starter và context. Bạn có thể dùng nhánh khởi đầu làm cơ sở để xây dựng dự án từ đầu hoặc nhánh ngữ cảnh để xem trước bản demo cuối cùng.
App khởi đầu cung cấp UI bạn cần cho ứng dụng cuối cùng, vì thế, bạn có thể tập trung vào triển khai logic cốt lõi. Mở terminal và chạy lệnh sau để nhân bản nhánh starter của repository vào máy cục bộ:
git clone -b starter https://github.com/makeuseofcode/Next.js-CRUD-todo-app.git
Chạy lệnh sau, trong thư mục dự án để cài đặt các phần phụ thuộc và khởi chạy server phát triển:
yarn && yarn dev
Hoặc:
npm i && npm run dev
Nếu tất cả đều chạy tốt, UI sẽ hiện trong trình duyệt của bạn:

Context API cung cấp một cách để quản lý và chia sẻ dữ liệu trạng thái trên các thành phần mà không cần prop drilling theo cách thủ công.
Tạo thư mục src/app/context để lưu file ngữ cảnh và giữ thư mục dự án được tổ chức tốt. Trong thư mục này, tạo file todo.context.jsx chứa tất cả logic ngữ cảnh cho ứng dụng này.
Nhập hàm createContext từ thư viện react và gọi nó, lưu trữ kết quả trong một biến:
import { createContext} from "react";
const TodoContext = createContext();
Tiếp theo, tạo một hook useTodoContext trả về TodoContext dưới dạng biểu mẫu khả dụng.
export const useTodoContext = () => useContext(TodoContext);
Để thực hiện CRUD (tạo, đọc, update, xóa) của ứng dụng, bạn cần tạo trạng thái và quản lý chúng với thành phần Provider.
const TodoContextProvider = ({ children }) => {
const [task, setTask] = useState("");
const [tasks, setTasks] = useState([]);
return <TodoContext.Provider value={{}}>{children}</TodoContext.Provider>;
};
export default TodoContextProvider;
Ngay trước lệnh return, tạo hàm handleTodoInput chạy khi các kiểu người dùng nằm trong to-do. Hàm này sau đó update trạng thái task.
const handleTodoInput = (input) => setTask(input);
Thêm hàm createTask chạy khi người dùng gửi một app to-do. Hàm này update trạng thái tasks và gắn ID ngẫu nhiên cho nhiệm vụ mới.
const createTask = (e) => {
e.preventDefault();
setTasks([
{
id: Math.trunc(Math.random() * 1000 + 1),
task,
},
...tasks,
]);
};
Tạo hàm updateTask ánh xạ qua danh sách tasks và update nhiệm vụ chứa ID khớp với ID của nhiệm vụ được click.
const updateTask = (id, updateText) =>
setTasks(tasks.map((t) => (t.id === id ? { ...t, task: updateText } : t)));
Tạo hàm deleteTask update danh sách tasks để nó bao gồm tất cả nhiệm vụ chứa ID không khớp với tham số được cung cấp.
const deleteTask = (id) => setTasks(tasks.filter((t) => t.id !== id));
Giờ bạn đã tạo trạng thái và viết code để quản lý chúng, bạn cần làm những hàm trạng thái và xử lý có sẵn cho Provider. Bạn có thể cung cấp chúng dưới dạng một đối tượng, dùng thuộc tính value của thành phần Provider.
return (
<TodoContext.Provider
value={{
task,
tasks,
handleTodoInput,
createTask,
updateTask,
deleteTask,
}}
>
{children}
</TodoContext.Provider>
);
Provider đã tạo phải chứa thành phần top-level để tạo ngữ cảnh sẵn có cho toàn bộ ứng dụng. Để làm việc này, chỉnh sửa src/app/page.jsx và bao gồm thành phần Todos với TodoContextProvider:
<TodoContextProvider>
<Todos />;
</TodoContextProvider>;
Chỉnh sửa file src/app/components/Todos.jsx và hủy cấu trúc tasks, task, handleTodoInput, và createTask qua cuộc gọi tới hàm useTodoContext.
const { task, tasks, handleTodoInput, createTask } = useTodoContext();
Giờ, update thành phần biểu mẫu để xử lý sự kiện gửi và đổi sang trường đầu vào chính:
<form onSubmit={(e) => createTask(e)}>
<input className="todo-input" type="text" placeholder="Enter a task" required value={task} onChange={(e) => handleTodoInput(e.target.value)} />
<input className="submit-todo" type="submit" value="Add task" />
</form>
Giờ bạn có thể dùng ứng dụng để tạo và thêm một nhiệm vụ vào list tasks. Để update hiển thị, bạn cần ánh xạ qua tasks hiện có và hiện chúng trong UI. Đầu tiên, tạo src/app/components/Todo.jsx chứa một mục cần làm.
Trong src/app/components/Todo.jsx, chỉnh sửa hoặc xóa một nhiệm vụ bằng cách gọi các hàm updateTask và deleteTask đã tạo trong tệp src/app/context/todo.context.jsx.
import React, { useState } from "react";
import { useTodoContext } from "../context/todo.context";
const Todo = ({ task }) => {
const { updateTask, deleteTask } = useTodoContext();
// isEdit state tracks when a task is in edit mode
const [isEdit, setIsEdit] = useState(false);
return (
<table className="todo-wrapper">
<tbody>
<tr>
{isEdit ? ( <input type="text" value={task.task}
onChange={(e) => updateTask(task.id, e.target.value)} /> ) :
(<th className="task">{task.task}</th> )}
<td className="actions">
<button className="edit"
onClick={() => setIsEdit(!isEdit)}> {isEdit ? "Save" : "Edit"} </button>
<button onClick={() => deleteTask(task.id)}>Del</button>
</td>
</tr>
</tbody>
</table>
);
};
export default Todo;
Để hiện src/app/components/Todo.jsx cho từng task, đi sâu vào file src/app/components/Todos.jsx và ánh xạ có điều kiện qua tasks ngay sau khi đóng thẻ header.
{tasks && (
<main>
{tasks.map((task, i) => ( <Todo key={i} task={task} /> ))}
</main>
)}
Kiểm tra ứng dụng trong trình duyệt và xác nhận nó cho kết quả mong đợi.

Hi vọng bài viết hữu ích với các bạn.
Nguồn tin: Quantrimang.com
Ý kiến bạn đọc
Những tin mới hơn
Những tin cũ hơn
Cách biến ảnh thật thành nghệ thuật cắt giấy 3D nhiều lớp bằng AI
Prompt tạo ảnh chân dung nghệ thuật đen trắng cực chất bằng AI
Viết bài đăng mạng xã hội thu hút sự chú ý với sự hỗ trợ của AI
Cách chuyển ghi chú viết tay thành infographic
20+ câu lệnh AI biến ảnh gốc thành nghệ thuật cắt giấy 3D nhiều lớp
Lên lịch và tạo hàng loạt bài đăng với sự trợ giúp của AI
Hướng dẫn xóa logo trong video bằng CapCut
Gắn kết và xây dựng cộng đồng trên mạng xã hội với AI
Phân tích và quyết định dựa trên dữ liệu với AI
Đo lường hiệu quả đào tạo: Mô hình Kirkpatrick
Xây dựng hệ thống đào tạo doanh nghiệp với AI
Cách tạo hình ảnh AI trên Gamma
Cách kết nối Google Docs với n8n
Prompt tạo ảnh mục tiêu kế hoạch trên ChatGPT nhiều phong cách
Hướng dẫn tạo trò chơi ô chữ Crossword trên Educaplay
Prompt tạo infographic món ăn cực đẹp bằng AI
Prompt tạo ảnh sản phẩm chuyên nghiệp như studio chụp quảng cáo
Framework ADDIE: Thiết kế hướng dẫn được tăng tốc bởi AI
Đánh giá nhu cầu đào tạo bằng AI
Xây dựng nội dung đào tạo bằng AI