Nay mình sẽ làm một ví dụ về Giỏ hàng( cart) trong Nextjs 13. Ở đây mình có kết hợp với Redux, Redux-Thunk , để xử lý thêm một sản phẩm vào giỏ hàng
Nếu bài viết này , bạn cảm thấy hay thì hãy chia sẻ nó , đó là ủng hộ tôi
Bạn nào chưa xem về Redux thì xem lại các bài viết trước của mình tại đây:
Trong bài viết này mình cũng vận dụng kiến thức ở các bài viết về Redux mà mình đã thực hiện thôi, nên cũng không có giải thích gì nhiều, vì đa phần React nó giống với NextJS rồi. Chỉ có điều là React nó chạy render ở client, còn Nextjs nó render trên server, chính vì thế nó hổ trợ cho việc chúng ta có thể SEO các từ khoá,....
Bố cục của nội dung hôm nay sau:
+ app/_assets/images : Dùng để lưu hình ảnh
+ app/_components/Header.tsx : Cấu hình giao diện cho header , hiển thị số lượng chỉ số sản phẩm có trong giỏ hàng
+ app/_libs/index.ts : Các thư viện cần cài đặt
+ app/_redux/actions/index.js : Cấu hình các action cho Redux, khi ta dispatch một action nó sẽ đi đên Reducers xử lý, nói chúng reducers nó đảm nhận sự thay đổi dữ liệu, sao đó nó mới cập nhật đến Stores, nên ta cần cấu hình các action cho nó dễ hiểu và maintain hơn
+ app/_redux/reducers/index.js : Nơi nhận các action gửi đến. Reducers nó sẽ nhận dạng các action để mà xử lý. Xử lý xong , nó sẽ cập nhật đến Stores
+ app/_redux/stores/index.js : Nơi lưu trữ các trạng thái (state) của hệ thống. Nó là nơi quản lý các State, giúp ta dễ dàng lấy ra dùng bắt cứ nơi nào trong Component
+ app/_redux/redux-provider.js : Nó sử dụng thành phần Provider từ thư viện react-redux để cung cấp store cho các thành phần con thông qua prop store. Các thành phần con được truyền vào thông qua prop children.
+ app/_redux/provider.tsx : Thành phần này được sử dụng để cung cấp chức năng của Redux store cho các thành phần con của nó. Kiểu PropsWithChildren<any> được sử dụng để định nghĩa prop children
+ app/_types/index.ts : Cấu hình các interface trong typescript, dùng nó để định dạng các kiểu dữ liệu , giúp ta dễ kiểm tra lỗi hơn
+ app/(route)/api/router.ts : Thiết lập đường dẫn route api, để gửi yêu cầu lấy tất cả sản phẩm , VD:/api/products
+ app/(route)/api/[id]/route.ts : Thiếp lập API, Gửi kèm theo ID của sản phẩm, để lấy thông tin của sản phẩm đó. VD: /api/products/12
+ app/(route)/cart/page.tsx : Thiếp lập giao diện hiển thị các sản phẩm mà người dùng đã mua có trong giỏ hàng(carts). Chúng ta lấy sản phẩm có trong giỏ hàng tại Stores của Redux
+ app/(route)/product/page.tsx : Trong component này ta cần hiện thị tất cả sản phẩm lấy được, từ hành động request /api/products/route.ts. VD: /api/products
+ app/(route)/product/[id]/page.tsx : Tại component này ta hiện thị của sản phẩm theo ID . Từ hành động request api/products/[id]/route.ts . VD: /api/products/12
+ app/page.tsx : Cấu hình component hiện thị
+ app/layout.tsx : Cấu hình bố cục hệ thống , đồng thời cấu hình Providers trong React-Redux vào để có thể sử dụng Redux trong các Component
+ .env : Tạo file .env ở thư mục tổng của hệ thống, thiếp lập các biến môi trường cho nó. VD: PATH_URL_BACKEND=https://dummyjson.com
Okay, vậy là xong, giờ ta đi sơ lượt qua các file bên trên thôi, mọi người có thể xem tại : Github
+ app/(route)/api/router.ts : Xây dụng phương thức GET . Giúp chúng ta request http://localhost:3000/api/products , nó sẽ gọi lấy tất cả sản phẩm từ api: https://dummyjson.com/products
+ app/(route)/api/[id]/route.ts : Lấy sản phẩm theo ID mà ta chèn vào link , request http://localhost:3000/api/product/[id] , nó sẽ lấy sản phẩm tại api : https://dummyjson.com/products/12
Thiếp lập Redux đã xong, như để sử dụng được ta cần phải cấu hình lại layout bố cục của ta
+ app/layout.tsx👍
import'./globals.css'importtype { Metadata } from'next'import { Inter } from'next/font/google'import Providers from'./_redux/provider'import Header from'./_components/Header'constinter=Inter({ subsets: ['latin'] })exportconstmetadata:Metadata= { title:'Create a simple example Cart in NextJS 13', description:'Create a simple example Cart in NextJS 13',}exportdefaultfunctionRootLayout({ children,}: { children:React.ReactNode}) {return (<html lang="en"><body className={inter.className}> <Providers><Header /> {children}</Providers></body></html> )}
+ app/page.tsx👍
import ProductPage from './(routes)/product/page'
export default function Home() {
return (
<div className='w-full max-w-6xl m-auto'>
<ProductPage />
</div>
)
}
Vậy là ta có thể sử dụng được rồi đó, giờ chỉ cần vào component và gọi và sử dụng thôi
Tiếp theo bạn nào siêng thì thiết lập các kiểu dữ liệu trong typescript , để giúp ta dễ dàng kiểm tra lỗi và ràng buộc kiểu dữ liệu cho hợp lý
+ app/_types/index.ts😂
Đoạn code trên mình có thêm useSelector , còn muốn gửi một action thì dùng thêm useDispatch
* useSelector : giúp ta lấy dữ liệu trong lưu trữ trong stores, code dưới đây nó sẽ lấy tổng số sản phẩm có trong giỏ hàng
* dispatch(DecreaseQuantity(key)) : gửi action xử lý việc giảm số lượng sản phẩm hiện tại theo key
* dispatch(IncreaseQuantity(key)) : gửi action xử lý tăng một sản phẩm hiện tại theo key
Okay vậy là xong, Nếu bạn thấy hay, thì hãy chia sẻ bài viết này! Đến với mọi người!