Banner 1
Banner 2
hero

Phạm Văn Tú

4518 thành viên

Giới thiệu

Developer, Blogger, Freelancer... Và một số cái đơ lơ thơ mơ khác...

Developer tại KOZOCOM - Viet Nam
Từng làm Developer tại GCO Software
Từng làm Developer tại IZI Software
Sống tại Đà Nẵng
Từng học tại Trường Đại học Sư phạm - ĐH Đà Nẵng
Đã học tại THPT Phan Thành Tài, Đà Nẵng

Routing trong nextjs

9/6/2024
lượt thích
hero
Bài tiếp theo của nextjs thì mình sẽ nói về routing trong nextjs nhé. Mình sẽ nói ngắn gọn nhất có thể để ae đọc hình dung dứt liền luôn nha ### Basic Thư mục **sign-in** có file **page.tsx** thì nextjs sẽ tạo ra đường dẫn webapp là **/sign-in** Trong thư mục phải có file page.tsx là bắt buộc nhen, file chỉ mục đường dẫn của nó luôn á. ### Nested routes Ví dụ mình muốn url **/course/lession** trong đó course sẽ là dynamic, mong muốn get value tên khoá học về để dùng query data. Thì mình sẽ tạo folder như sau **[** **course]/lesson/page. ****tsx** -> nó sẽ có url kiểu kiểu như **react-course/lesson?slug=bai-1** đương nhiên `react-course` là động nha. Case này gọi là `dynamic segment`. Segment ae hiểu như là thư mục cho dễ hiểu hen. Tóm cái quần lại là mục đích để lấy params ra để xử lý gọi api hay gì đó…À đừng để 2 thư mục [dynamic] cùng cấp nha ae, vì nextjs không hiểu mình vô thằng nào á nè Còn nếu ae muốn url cứng hết thì đơn giản chỉ cần tạo **folder course** trong folder course có **folder lession** thì url sẽ luôn luôn là course/lession nè. Nếu không đúng url course/lession thì nó bắn lẹ page 404 liền. Cái này thì đơn giản hơn nhiều hen ### Group Group thì nó không tạo ra routing nha ae. Mục đích là để gom nhóm các routing liên quan vào chung ví dụ mình sẽ tạo thư mục **(dashboard)** thì sẽ không tạo ra route /dashboard đâu nha nếu vào thì ra 404 liền đoá ### Catch-all Segments Ví dụ mình có folder như sau **shop/[…shop]** thì nó sẽ chấp nhận các route như /sign-in/a, /sign-in/b nếu vào /sign-in thì sẽ báo not-found liền ### Catch-all Segments Ví dụ mình có folder như sau **shop/[…shop]** thì nó sẽ chấp nhận các route như /sign-in/a, /sign-in/b và bao gồm luôn route /sign-in luôn nha. Khác mỗi cái trên vậy thui đó ### Params Thông thường là dynamic routes. Như ví dụ ở trên có thư mục **[** **course]/lesson** có url là **react-course/lesson** thì params là 1 object có key là course value là “react-course”. Dễ chưa =)) ### SearchParams Thường là những query ở trên URL ví dụ **lesson?slug=html-css.** Thì slug chính là searchParams. Log ra thì nó cũng là 1 object có key là slug value là ‘html-css” Sương sương vậy thui đó, dễ ăn, dễ trúng thưởng 😜. Hẹn ae bài tiếp theo nhennn Routing trong nextjs
Thích ()
Bình luận(1)
shareChia sẻ

Sử dụng font trong nextjs

3/6/2024
lượt thích
hero
Say hi những người ae, TuPV comeback đây kaka lâu ngày quá rồi để cái blog mốc mêuuuu luôn á kaka. Thôi thì NextJs ra vừa ra bản [NextJs15 RC](https://nextjs.org/blog/next-15-rc) cách đây mấy ngày thì thôi đu theo luôn cho nó trending tí nhen. Bài này sẽ là khởi đầu cho những bài về NextJs về sau nha, viết vội chứ chuẩn bị cưới vợ rồi dí lắm 😆. Bài viết này mình sẽ list những cách dùng font như từ google fonts, font weight, variables, multiple fonts, local fonts, tailwind fonts…gét goooooo 😜 Mình sẽ để font ở trong layout.tsx nha. Mặc định cài nextJs đã có next/font và tối ưu luôn cho mình sẵn rồi. Nếu mình dùng link cdn để nhúng font vào thì cũng được okie, nhưng load lần tiên sẽ bị kiểu như nháy 1 phát từ font mặc định sang font mình nhúng cdn, nó chưa apply vô kịp á gọi là [Layout Shift](https://web.dev/articles/cls) cho nó bài bản 😁. Nhưng mà nếu dùng font google có sẵn những font trong này [Font Google](https://fonts.google.com/variablefonts) thì sẽ tự động cache lại bất kỳ font nào ở đây. ``` import { Manrope, Roboto } from "next/font/google" // Khai báo const manrope = Manrope({ subsets: ["latin"] }) const roboto = Roboto({ subsets: ["latin"], weight: ["400", "500"]}) // Sử dụng {children} Pham Van Tu ``` Tuỳ font mà nó sẽ yêu cầu weight hay không nhưng thường nên note những font weight mình dùng trong hệ thống và 1 mảng nha. `Vì nếu không truyền là nó auto lấy hết font weight của chữ đó có luôn á :D`, thừa quá không cần nè. Dự án sẽ có nhiều font thì mình nên đặt tên biến cho từng font ``` // Khai báo variable export const manrope = Manrope({ subsets: ["latin"], variable: "--font-manrope", }) export const roboto = Roboto({ subsets: ["latin"], variable: "--font-roboto", weight: ["400", "500"], }) // Khai báo variable sử dụng {children} // Defined common body { font-family: var(--font-manrope) } p { font-family: var(--font-roboto) } ``` **Vậy sử dụng biến trong Tailwind Css như thế nào và ví dụ như font không có trên google font thì sao nào 👇** Tại file tailwind.config khai báo giúp mình như sau ``` theme: { extend: { fontFamily: { primary: ["var(--font-manrope)"], secondary: ["var(--font-roboto)"], }, }, }, ``` Khi sử dụng thì đơn giản là `<h1 className="font-primary">Phạm Văn Tú </h1>` là có font manrope rồi nè Vậy sử dụng local font dưới máy thì ae bỏ font trong app rồi ae dùng như dưới nha, dùng thì tương như ở trên mình có thể để class trong thẻ body sét fontName.classname là okela rồi ``` import localFont from "next/font/local"; // Nếu mà font có 1 style thôi thì ae có thể để string thôi cũng được cho ngắn gọn const dm_sans = localFont({ src: "" || [ { path: "", weight: "", style: "italic", }, ], display: "swap", }); ``` `` **Note** : Ae nên sẽ tạo ra 1 file fonts.ts chẳng hạn rồi defined font các kiểu gì đó ra rồi import dùng ở layout cho okie hơn hi. Cái này nextjs khuyến cáo nên zị á 😇 cho nó smooth performer hơn `` Đến đây là hết gòi, hóng bài sau cùng TuPV nhen, buy mọi ngườiiiiiiii 🤭 ``
Thích ()
Bình luận(1)
shareChia sẻ

Responsive hình ảnh, video theo tỉ lệ

2/1/2024
lượt thích
hero
Hello mấy ae 2024, lâu lâu lại chọt 1 bài lên gọi là có tính duy trì viết bài chút 😆. Bài viết này mình sẽ làm giới thiệu responsive hình ảnh, video theo tỉ lệ tuỳ thích nhé, gét goooo Khi chúng ta làm theo thiết kế có sẵn khung nào đó thì khoẻ rồi hen, có nhiêu xét nhiêu thui không thành vấn đề nhưng đôi khi người ta muốn hiển thị video, hình ảnh theo tỉ lệ 16: 9 hoặc 4:3 hoặc tỉ lệ nào đó…thì các bạn xem ví dụ ở dưới nha
Thích ()
Bình luận(1)
shareChia sẻ

Viết script tự động hoá Postman

24/9/2023
lượt thích
hero
Sau khi ae biết Postman là gì và dùng cơ bản được qua bài viết [Sử dụng Postman cho test API](https://v0.phamvantu.com/su-dung-postman-cho-test-api) thì bài viết này mình thử viết script cho nó xem sao nhé. Gét gooooo 🤪 Bài biết này mình sẽ viết script để nó tự động hoá lưu access_token và refresh_token vào environment của Postman nhé. Tương tự như bài trước thì mình sẽ set access_token cho foder cha cho nó nhé nhưng token thì mình sẽ lấy từ trong environment ra nha Viết script tự động hoá Postman Nếu như cách thủ công thì sau khi login xong trả về access_token và refresh_token rồi mình copy set nó vào biến environment để các api các cần token để dùng. Trường hợp access_token hết hạn mau quá thì mình phải gọi request refresh_token để nhận được access_token mới rồi copy sang nữa thì hơi… 😳. Hên là Postman hỗ trợ mình viết script để nó tự động hoá cho mình luôn ròiiii Viết script tự động hoá Postman Ae sẽ thấy 2 loại Script là Pre-request Script và Test thì tương ứng đó là script chạy trước khi gửi và script chạy sau khi gửi. Cái này viết theo ngôn ngữ Javascript nhưng viết theo format Postman. Khi mình chạy request login xong thì nó kiểm tra thử status có bằng 200 hông, nếu bằng thì đoạn test mình okie chạy thành công. Mình sẽ lấy response từ Postman ra bằng cách `pm.response.json()` và sẽ set vào các giá trị mong muốn environment thuii Tương tự các request khác thì ae muốn set vào environment thì làm tương tự như trên còn không thì chỉ cần check status = 200 là thành công gòiii Viết script tự động hoá Postman Trường hợp access_token hết hạn thì mình gọi request refresh-access-token để cập nhật lại access_token mới trong environment và những api khác cần token để gửi lên headers vẫn mướt mườn mượt luôn 😝 Viết script tự động hoá Postman Hết ròi!!!. Hy vọng bài viết này giúp ae khỏi copy gán gán như mình lúc trước nữa ahihi 😁
Thích ()
Bình luận(1)
shareChia sẻ

Sử dụng Postman cho test API

24/9/2023
lượt thích
hero
Chắc ae cũng khá quen với công cụ Postman dùng để test api rồi. Nhưng mình cũng cũng nói sơ lại cho ae newbie có đọc bài này thì cũng hình dung nó là gì nha. Thường ae backend code api thì họ test ở trên này luôn cho tiện thay vì gọi javascript hay axios bla bla để test xem okie hay chưa. Hoặc như ae nhận 1 list api từ BE và ae muốn check lại api trả về đúng định dạng ae muốn hay chưa thì dùng postman test luôn. Ae có thể download phiên bản phù hợp tại link chính thức của nó [tại đây](https://www.postman.com/) nhé. Bên sidebar có `Collection` nằm đầu tiên. Nó như 1 folder vậy á, thường mình sẽ chia mỗi dự án là mỗi Collection riêng. Vd mình có 2 api get list user và api create user như bên dưới Sử dụng Postman cho test API Sử dụng Postman cho test API Ở đây mình đang bị lặp `https://reqres.in/api` nên mình sẽ tạo 1 biến để dùng lại. Thì biến ở Postman gọi là environment. Ae có thể chọn bên sidebar dưới mục Collection rồi tạo mới 1 environment để dùng nha. Sử dụng Postman cho test API Và khi tạo xong qua lại 2 request lúc nãy mình cập nhật lại `https://reqres.in/api thành {{host}}` rồi test lại nhé, nhớ là mình phải set environment bên góc phải trên cho nó rồi mới chạy được nha. Sử dụng Postman cho test API Trường hợp request cần truyền token lên thì mình set bên tab Authorization và chọn type tương ứng với bên api setup nha, thường sẽ là Bearer Token như hình bên dưới.Sử dụng Postman cho test API Sau khi gọi request này thì bên Headers sẽ gửi lên key là Authorization với value là token mình set ứng lúc nãy Sử dụng Postman cho test API Vậy lỡ có nhiều request cần token gửi lên thì sao. Vậy thì mình set token ở folder cha của nó rồi các request con kế thừa là được nha. Như hình dưới mình Folder cha có Type là Bear Token và set token cho nó luôn Sử dụng Postman cho test API Ở request con mình chỉ cần chọn Authorization là `Inherit auth from parent` là okie rồi Sử dụng Postman cho test API Hy vọng bài viết này sẽ giúp ae hiểu và sử dụng được công cụ này hiệu quà nhé. Bài viết sau mình sẽ giới thiệu viết script tự động hoá Postman nha. Ví dự như khi login xong thì mình có được accessToken và refreshToken và nó sẽ tự động lưu vào các biến môi trường của mình rồi mình đem đi gán cho các request cần truyền token lên header chẳng hạn nha hehe. Baiiiiii 😝
Thích ()
Bình luận(1)
shareChia sẻ

Tối ưu kích thước file build cho production

4/9/2023
lượt thích
hero
Hi ae, bài viết này xem tìm xem thử cái nào chiếm dung lượng nhiều trong project của mình và optimized nó nhé. Nếu mình chỉ build thông thường thì khó mà phát hiện ra cái gì chiếm nhiều dung lượng, mình dùng vite nên ở đây mình giới thiệu công cụ [Rollup Plugin Visualizer](http://npmjs.com/package/rollup-plugin-visualizer), thằng Vite được build dựa trên thằng Rollup nên dùng nó để phân tích file build nhé, nếu anh ae dùng webpack thì có package [webpack-bundle-analyzer](https://www.npmjs.com/package/webpack-bundle-analyzer) tương tự nhé. Khi mình chạy build nó sẽ cho xuất ra cho mình 1 file chỉ số stats.html cùng cấp với package.json của mình luôn. Ae có thể mở lên và theo dõi chỉ số nhé và check thử cái nào cần tối ưu được thì mình tối ưu cho nhẹ nha. Dùng cái nào thì import cái đó thôi thay vì import cả thư viện vào -> Tree-shaking Tối ưu kích thước file build cho production Sau khi tối ưu thì ae có thể tự check kích thước file build của mình nhé đương nhiên là nhỏ hơn rồi 😝, và load lại file stats tận hưởng thành quả nha 🥰 Tối ưu kích thước file build cho production Hy vọng bài viết này sẽ giúp ae phân tích file build và có thể tối ưu nó lại nhé với giao diện theo dõi trực quan okie luôn
Thích ()
Bình luận(1)
shareChia sẻ

Lazyload component với react lazy

4/9/2023
lượt thích
hero
Nghĩ lễ 2/9 sâu quá ghé blog chém gió xíu xíu chớ ae quên mình mất 😆 Đôi lúc ae code nhiều nhưng quên mất lúc build để deploy lên production thì không biết ra sao hè. Ae mở package.json và xem thử lệnh build như thế nào nhé Lazyload component với react lazy dev: để ae dev quen quá rồi :v build: chạy vite build preview: chạy file build của chúng ta. Ví dụ sau khi build ra được file js, html, css thì preview nó sẽ chạy cái những file này lên cho chúng ta Sau khi build nó sẽ nằm trong thư mục dist của chúng ta, gzip trên hình là nó 1 file nén lại từ file build ra. Và khi deploy lên server là nó sẽ deploy thằng dist này lên chứ mình không deploy cái src nha. Mục src để mình code thoiii. Để chạy bản production lên thì chạy yarn preview. Mọi người sẽ thấy toàn bộ app mình sẽ dồn toàn bộ javascript thành 1 file nặng gần 200 kiB sau khi đã được nén. Sau khi chạy yarn preview thì ae chọn tab network và chọn tab js, nó sẽ chạy mỗi cái file js sau khi build ra Trường hợp mình có trăm page, trăm component khi load lần đầu bắt người dùng tải toàn bộ về thì hơi phí mất time hơn 🤪. Điểm thuận lợi thì cũng có là nó tải toàn về nên chuyển route nó nhanh vãi vì nó tải toàn bộ về lần đầu rồi. Ở đây mình sẽ dùng kỹ thuật lazy load dùng đến đâu tải đến đó nhưng chuyển route thì hơi chậm 1 tí xíu nhưng chắc mình cũng không nhận ra lắm :)), do nó cần down js từ server về nữa. Dùng lazy thì cần 1 component <Suspense> để bao bọc nó nữa nhé, nó 1 fallbackUI, ví khi vào trang chưa load xong thì show tạm ra gì đấy chẳng hạn, không truyền cũng không sao, ra màn hình trắng thoi 😇 Lazyload component với react lazy Ví dụ khi mình dùng lazy load cho page Login thì khi vào trang login nó mới tải js trang này về chứ ban đầu nó không tải toàn bộ nữa. Và khi mình build lại thì không còn 1 file js nữa mà sẽ ra nhiều file js khác kích thước cũng giảm hơn so với ban đầu mình không dùng :v Khi mình dùng lazy load thì mình cũng cải thiện được cái Lighthouse nữa nha, công cụ của chrome để test performance. Không phải lúc nào cũng ra 1 kết quả nên mình tính tương đối sai số mỗi lúc chạy nhé ae, 1 phần do mạng mẽo đồ nữa nghen. Ở đây có những chỉ số của trang web mình ae có thể dựa vào đây để test và cải thiện những chỉ số theo hướng dẫn của nó nhé Lazyload component với react lazy Hy vọng bài viết này giúp ae cải thiện được chút performance project của mình nhé. Thank you for watchinggggg 😜
Thích ()
Bình luận(1)
shareChia sẻ

Tạo Modal với React Portal

7/7/2023
lượt thích
hero
Say hi những ngừi ae của toiiiii. Bài viết này là khai bút con Mạc Bục đã mua cách đây 2 tuần của toiiii kaka. Máy chạy nhanh quá làm mình cũng quên luôn viết bài trên blog của mình hehe. À blog được tài trợ bởi server của ngừi anh thân thương [Thành Trung](https://thanhtrungit.net/). Ai mua VPS hay hosting thì có thể ghé [Dnclound.vn](https://dncloud.vn/) bao rẻ-khoẻ luôn nha ahihi. Thôi văn vở quá rồi kéo xuống thoiiiii 😂 Api này rất là hữu ích trong việc ae tạo modal, popup đó là `Create Portal`. Giúp mình tạo ra những component nằm trong bất kỳ vị trí nào trên page của chúng ta. Vậy tại vì sao nên sử dụng nó hè 🤙 React app của chúng ta được render trong element có id root chẳng hạn, thì ở đây sẽ render cả cái app chúng ra luôn. Trong 1 số trường hợp chúng ta muốn sử dụng Modal của mình nằm ngoài component nào đấy hoặc nằm ngoài id root luôn thì chúng ta sử dụng react portal nhé 🤙 Giả sử mình có 1 sidebar bên trái, content bên phải và trong content có 1 modal confirm nhé Trường hợp xảy ra là z-index của sidebar: 20, z-index của content:10 Bây giờ cho dù z-index của modal confirm của mình tăng lên bao nhiêu đi nữa thì cũng không có tác dụng đâu vì thằng cha của nó là content nhỏ hơn moà. Trong những trường hợp này mình có thể đưa thằng modal ra ngoài cùng cấp với sidebar hoặc tốt hơn ra ngoài root luôn Cách dụng thì ae sẽ import createPortal vào nhé, `có 2 tham số đầu tiên là jxs, tham số thứ 2 là element` chúng ta muốn chèn vào. Ví dụ muốn chèn vào body thì đơn giản chỉ cần document.body là okie rồi nè. Trong trường hợp ae muốn chèn vào element nào thì get element nó ra và dùng thoi ``` const root = document.getElementById('root') as HTMLElement export default function Confirm({ visible, ok, cancel }: ConfirmProps) { const handleOk = () => { ok() } const handleCancel = () => { cancel() } return createPortal( Are you sure? OK Cancel , root ) } ``` Nợ demo nha ae 🤪. Có thì thắc mắc thì cứ ping mình giải thích nhé hihi. Chúc ae new day zui zẻ nhé 🤪
Thích ()
Bình luận(1)
shareChia sẻ

useCallback trong react

23/6/2023
lượt thích
hero
Hi 500 ae. Bài này mình giới thiệu về 1 hook là `useCallback` cũng như sử dụng nó ra sao nhé. Lướt thuiiiii Chúng ta thường dùng `useCallback` khi mình không muốn function của chúng ta được khởi tạo lại mỗi lần component chúng ta re-render ``` const memoizedCallback = useCallback(() => { doSomething(a, b) }, [a, b]) ``` Cách dùng thì tham số đầu tiên là 1 callback thực hiện việc gì đấy tham số thứ 2 là dependence. Mỗi lần dependence thay đổi thì function được chạy lại. Đơn giản vậy thuii Mình có để demo phía dưới thì mình có 1 function handleClickTitle nó nhận vào value. Function là 1 object nên khi component re-render thì handleClickTitle sẽ tạo tham chiếu mới nên sẽ làm component re-render lại thôi. Trường hợp này mình dùng useCallback như demo dưới bạn có thể vọc để chạy nhé 😅
Thích ()
Bình luận(1)
shareChia sẻ

React.memo và useMemo trong React

19/6/2023
lượt thích
hero
Say hi 5 chăm ae, bài này sẽ là bài đầu tiên trong chuỗi React Hook nâng chình xíu nhé. Bỏ qua các hook basic như useState, useEffect, useContext…Hơi nhiều lời rồi, lướt thoiiiii Chắc ae đã biết thì component sẽ re-render state hoặc props được cập nhật, compoent cha re-render khiến component con cũng re-render theo. Vậy để không muốn component con bị re-render mỗi khi component cha re-render thì chúng ta dùng `React.memo` nhé ### **React.memo()** React.memo() là 1 HOC (Higher-order component), chứ không phải hook React.memo() dùng cho functional component Chỉ render lại component nếu props thay đổi, còn không thì render lại kết quả của props cũ => có sử dụng kỹ thuật Memozation Sử dụng shallow comparison ``` import "./styles.css"; import Title from "./components/Title"; import { useState } from "react"; export default function App() { const [count, setCount] = useState(0); const handleClick = () => { setCount((prev) => prev + 1); }; return ( Click to increase count Count: {count} ); } ``` Ae thấy component `<Title/>` chắc chắn sẽ bị re-render khi mình click button, component cha re-render kéo theo nó cũng bị re-render theo. Nếu như component `<Title/>` tính toán nhiều nặng thì về performent không tốt còn ít thì hông đáng là bao 😉. Thay vì mình export như bình thường mình sẽ export như bên dưới `React.memo(NameComponent)`. ``` import React from "react"; export default function Title() { console.log("title"); return This is Title; } --------------Convert to ----------> import React from "react"; function Title() { console.log("title"); return This is Title; } export default React.memo(Title); ``` `React.memo` chỉ check props thôi nha. Nếu như state trong component Title thay đổi thì nó vẫn re-render bình thường nha. Ngoài tham số là tên component thì sẽ nhận 1 function nữa nhé. Function này có 2 tham số, khi function đó return true thì props trước và sau giống nhau -> không làm component re-render. Ngược lại khác nhau thì render lại thuiiii. À ví dụ ae truyền 1props qua component con dạng không nguyên thủy như object đồ á thì nó vẫn khiến component con re-render bình thường nha. Vì mỗi cần component cha re-render thì nó sẽ thay đổi cái tham chiếu của object props mình truyền sang nên component con tưởng props thay đổi nó re-render lại. ``` interface TitleProps { address: { street: string; }; } function Title(props: TitleProps) { console.log(props.address); return This is Title; } function equal(prevProp: TitleProps, nextProps: TitleProps) { return prevProp.address.street === nextProps.address.street; } export default React.memo(Title, equal); ``` Các bạn để ý thì mỗi lần App chúng re-render thì nó sẽ tạo 1 instance address mới làm cho component React memo không còn hoạt động như mong muốn nữa, làm mình phải sử dụng thêm equal function hơi rườm rà. Thì để hạn chế address được khởi tại thì mình dùng useMemo. Nào mình dùng những state, props liên quan muốn control thì mình truyền vào dependence như là bên useEffect vậy khi nào nó có sự thay đổi thì sẽ làm cho address tạo 1 instance mới làm cho Title chúng ta re-render lại còn mặc định [] thì sẽ chạy lần đầu tiên hoiiiii Những vấn đề liên quan đến meno thì nó sẽ dùng ram của máy tính, càng dùng nhiều thì càng tốn nhiều ram, bù lại có được performance tốt hơn nên là ae cân nhắc khi dùng nha. Không phải gì cũng meno hết, vậy thì tốn ram nặng, những điện thoại yếu yếu tràn ram đơ cái máy tội lắm luôn :v ``` const address = useMemo(() => { return { street: K29 Nguyễn Như Đãi, Đà Nẵng" } }, []) ``` Hy vọng sẽ giúp các bạn có thể được cải thiện được performance trong dự án nha, tránh được việc re-render các component không cần thiết nhé
Thích ()
Bình luận(1)
shareChia sẻ
hero