- vừa được xem lúc

Blog#39: Tái sử dụng code và Clean Code với React Hooks 😊 (Series: ReactHayHo - PHẦN 1)

0 0 18

Người đăng: NGUYỄN ANH TUẤN

Theo Viblo Asia

Mình là TUẤN hiện đang là một Full-stack Developer tại Tokyo 😉. Nếu bạn thấy Blog này hay xin hãy cho mình một like và đăng ký để ủng hộ mình nhé 😊.

Cải thiện khả năng tái sử dụng với Custom Hooks

Nếu bạn nhớ lại những ngày mà trước khi phiên bản React 16.8.0 ra đời. Cách lifecycle của component được xử lý trong componentDidMount, componentDidUpdatecomponentWillUnmount. Mỗi hàm lifecycle thường chứa logic không liên quan trong khi các logic liên quan lẫn nhau lại được tách ra. Điều này thường dẫn đến các component trở nên phức tạp khó tái sử dụng, dễ bị lỗi và không nhất quán.

Sau đó, trong React 16.8.0 hook đã được update mục đích để cải thiện những vấn đề hàng ngày mà rất nhiều Dev React đang gặp phải và vật lộn với nó.

Hooks cho phép bạn chia một component thành các chức năng nhỏ hơn dựa trên những phần có liên quan (chẳng hạn như thiết lập đăng ký hoặc tìm nạp dữ liệu), thay vì buộc chúng phải được phân chia dựa trên các hàm lifecycle.

Điều này rất tuyệt vời để giữ sự phân tách tốt các mối quan tâm, nhưng cũng để giữ cho code của bạn DRY. Hooks cho phép bạn trích xuất các logic state để có thể kiểm tra độc lập và tái sử dụng trong các component khác. Điều này làm cho logic state ít bị lỗi hơn và cung cấp khả năng phân tách các mối quan tâm tốt hơn. Views cũng trở nên rõ ràng hơn và không bị lộn xộn với logic phức tạp.

Các hook không chỉ dùng để thay thế các hàm lifecycle bằng cách sử dụng useEffect.

Hãy xem ví dụ sau nơi chúng ta đang tạo một ArticlePreview component, đại loại như thế này:

React component — Article Preview

Bạn có thể giễ dạng bị một thế lực nào đó cám dỗ và viết một cái gì đó như thế này:

import { useEffect, useState } from "react";
import { Card, Header, Title, Subtitle, Avatar, Actions, Image, Button
} from "./components"; export default function ArticlePreview({ id }) { const [loading, setLoading] = useState(false); const [article, setArticle] = useState(null); useEffect(() => { setLoading(true); fetch(`/articles/${id}`, { method: "POST" }) .then(setArticle) .then(() => setLoading(false)); }, [id]); const dislike = () => { fetch(`/articles/${id}/dislike`, { method: "POST" }); }; const like = () => { fetch(`/articles/${id}/like`, { method: "POST" }); }; return ( <Card inProgress={loading}> <Header> <Title>{article?.title}</Title> <Subtitle>{article?.subtitle}</Subtitle> <Avatar src={article?.author?.image} /> </Header> <Image src={article?.banner} /> <Actions> <Button primary onClick={like}> Like </Button> <Button secondary onClick={dislike}> Dislike </Button> </Actions> </Card> );
}

Vấn đề với cách tiếp cận này là bạn có rất nhiều logic state được trộn lẫn bên trong component của mình. Điều này làm cho logic state khó kiểm tra độc lập và cũng không thể tái sử dụng trong các component khác, chẳng hạn như ArticleFull component bên dưới:

React component — ArticleFull

Có thể sử dụng một cách tiếp cận tốt hơn sẽ là tạo một Hooks tùy chỉnh useArticle xử lý logic state có thể tái sử dụng cho cả component ArticlePreviewArticleFull. Một useArticle Hooks có thể trông giống như thế này:

import { useEffect, useState } from "react"; export default function (id) { const [loading, setLoading] = useState(false); const [article, setArticle] = useState(null); useEffect(() => { setLoading(true); fetch(`/articles/${id}`, { method: "POST" }) .then(setArticle) .then(() => setLoading(false)); }, [id]); const dislike = () => { fetch(`/articles/${id}/dislike`, { method: "POST" }); }; const like = () => { fetch(`/articles/${id}/like`, { method: "POST" }); }; return [like, dislike, loading, article];
};

Và với logic state được trích xuất vào Hooks tùy chỉnh của riêng nó, view/component có thể trông giống như thế này:

import { Card, Header, Title, Subtitle, Avatar, Actions, Image, Button
} from "./components";
import { LikeIcon, DislikeIcon } from "./icons";
import useArticle from "./useArticle"; export default function ArticlePreview({ id }) { const [article, loading, like, dislike] = useArticle(id); return ( <Card inProgress={loading}> <Header> <Title>{article?.title}</Title> <Subtitle>{article?.subtitle}</Subtitle> <Avatar src={article?.author?.image} /> </Header> <Image src={article?.banner} /> <Actions> <Button onClick={like}> <LikeIcon /> </Button> <Button onClick={dislike}> <DislikeIcon /> </Button> </Actions> </Card> );
}

Mặc dù đây chỉ là một ví dụ đơn giản, nhưng việc phân tách các mối quan tâm sẽ tốt hơn nhiều với logic state được chuyển sang custom hook có thể giễ dàng tái sử dụng và với nó component này sạch hơn rất nhiều, dễ đọc và giễ maintenance.

Như bạn có thể thấy custom hooks là một cơ chế tuyệt vời clean code và có thể tái sử dụng!

Roundup

Như mọi khi, mình hy vọng bạn thích bài viết này và học thêm được điều gì đó mới.

Cảm ơn và hẹn gặp lại các bạn trong những bài viết tiếp theo! 😍

Nếu bạn thấy Blog này hay xin hãy cho mình một like và đăng ký để ủng hộ mình nhé. Thank you.😉

Ref

Bình luận

Bài viết tương tự

- vừa được xem lúc

Học Regular Expression và cuộc đời bạn sẽ bớt khổ (Updated v2.2)

. Regular Expression (RegEx) à? Nghe quen quen. . Bạn cần xử lý validate (kiểm tra tính hợp lệ) các trường dữ liệu nhập vào ô Text. .

0 0 93

- vừa được xem lúc

Naming rules - Các quy tắc vàng trong làng đặt tên

. . Đã bao giờ bạn gặp khó khăn khi phải suy nghĩ nên đặt tên biến/hàm như thế nào trong lúc code.

0 0 25

- vừa được xem lúc

Tóm tắt cuốn Clean Code của Uncle Bob

Bài viết được dịch từ Gist của wojteklu. . Quy tắc chung. .

0 0 92

- vừa được xem lúc

Tôi đi học code - lớp mẫu giáo

Chào mừng các bạn quay trở lại với blog duthaho.com.

0 0 49

- vừa được xem lúc

Lean Code CSS

Khi thiết kế và phát triển web, đôi lúc chúng ta gặp khó khăn trong việc tổ chức và quản lý code CSS. Nhiều nhà thiết kế website nghĩ rằng việc tổ chức và quản lý code thật là rắc rối, tuy nhiên nếu b

0 0 23

- vừa được xem lúc

Design Patterns là gì? Tại sao nó lại là trợ thủ đắc lực của Developers

Design Pattern là một giải pháp chung để giải quyết các vấn đề phổ biến khi thiết kế phần mềm trong lập trình hướng đối tượng OOP. Design pattern là các giải pháp tổng thể đã được tối ưu hóa, được tái

0 0 49