Viblo Code
+22

Sài Gòn thì đau lòng nhưng nhúng TypeScript vào ReactJS thì chưa chắc

■ Intro.

Đợt đầu tháng, mình có trao đổi với người anh về việc triển khai TypeScript trong dự án. Là một người đã có trải nghiệm nhiều với ngôn ngữ lập trình này, anh thao thao:

- Ai rồi cũng phải dùng TypeScript thôi mà (J4F) =))

rồi spoil cho một vài điểm nổi bật của nó. Cá nhân mình tiếp cận với TypeScript trong Angular một thời gian nên cũng hiếu kỳ, không biết sang ReactJS thì nó sẽ "dư lào" 😄 😄))

Để kiểm chứng nhận định trên của người anh, hãy đồng hành cùng mình trong bài viết này nhé!

■ Target

Để tìm hiểu về việc nhúng TypeScript vào dự án ReactJS, chúng ta tập trung chủ yếu về:

  • Lý do chọn TypeScript.
  • Cấu hình dự án ReactJS kết hợp với TypeScript.
  • Một số ví dụ cơ bản thường gặp.

Do đó, bài viết sẽ hướng tới các bạn đã nắm qua cơ bản về ReactJS và một chút xíu xiu về TypeScript rồi nha các homies ^^

Nhấp một ngụm Espresso và bắt đầu nào!

■ Why TypeScript?

Theo Trang chủ:

TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.

TypeScript được phát triển bởi Microsoft và cộng đồng mã nguồn mở.

"Superset" ở đây có thể được hiểu là:

TypeScript = JavaScript + some amazing stuffs <3

Hãy cùng ngó qua Biểu đồ xu hướng phát triển của một số ngôn ngữ lập trình phổ biến một chút:

Có thể nói TypeScript đang có xu hướng "re-trending" trong những năm trở lại đây 😄😄))

Ngoài sở hữu những đặc điểm của JavaScript, điều TypeScript làm mình ấn tượng hơn cả là về việc hỗ trợ static typing. Thành thật mà nói, đợt đầu mình cảm thấy "không thoải mái" lắm vì đã quen với dynamic typing bên JavaScript rồi, nghĩ bụng ngôn ngữ này thật là khó tínhh quá đi mà >.< (J4F)

Tới giờ thì suy nghĩ khác chút, chúng ta có thể quản lý dữ liệu và luồng dữ liệu chặt chẽ hơn nhờ có TypeScript.

Cùng nhau cấu hình một dự án nhỏ rồi xem TypeScript đã thuyết phục mình như thế nào!

■ How to config?

Ngay từ cuối 2018, React team đã ra mắt bản Create React App 2.1 có hỗ trợ TypeScript đầy đủ.

Để bắt đầu init một dự án ReactJS mới với Create React App tích hợp TypeScript, chúng ta chạy lệnh:

npx create-react-app PROJECT_NAME --template typescript
// OR
yarn create react-app PROJECT_NAME --template typescript

Trường hợp đã có dự án ReactJS trước đó rồi thì thể cài đặt thêm TypeScript thông qua:

npm install --save typescript @types/node @types/react @types/react-dom @types/jest
// OR
yarn add typescript @types/node @types/react @types/react-dom @types/jest

sau đó đổi một số files đuôi .js/.jsx thành .ts/.tsx.

Tiếp theo chỉ cần Restart server & enjoyyy 🎉🎉


Notes:

Một số tuỳ chọn biên dịch trong tsconfig.json:

{
    "compilerOptions": {
        "jsx": "react",
        "module": "commonjs",
        "noImplicitAny": true,
        "outDir": "./build/",
        "preserveConstEnums": true,
        "removeComments": true,
        "sourceMap": true,
        "target": "es5",
        // ...
     },
     "include": [
        "src/components/index.tsx",
        // ...
     ],
}

Để tìm hiểu thêm, bạn có thể xem chi tiết tại đây.

Phần tiếp theo, chúng ta sẽ đi vào một số ví dụ khi sử dụng TypeScript trongReactJS nhé!

■ How to implement?

■ Component

Với Functional Component:

// Declare
import React, { FC } from 'react';

type PostProps = {
    link: string,           // Required props
    hasSupportMe?: boolean, // Optional props
};

const Post1 = ({ link, hasSupportMe }: PostProps) => ( /* ... */ );
const Post2: FC<PostProps> = ({ link, hasSupportMe }) => ( /* ... */ );

// Use
<Post1 link="https://haodev.wordpress.com" hasSupportMe={true} />
<Post2 link="https://haodev.wordpress.com" hasSupportMe={false} />

Thoạt nhìn thì cách khai báo Post1Post2 khá giống nhau nhưng cách khai báo Post2 cho phép mình có thể lấy thêm các options khác nữa, cụ thể:

const Post2: FC<PostProps> = ({ link, hasSupportMe, children }) => ( /* ... */ );

Với Class component:

// interface PostProps, PostState

class Post3 extends React.Component<PostProps, PostState> {
    constructor(props: PostProps) {
         super(props)
    }
    
    return ( /* ... */ );
};

Để khai báo default props cho component:

// Function component
const Post1 = ({
    link = "https://haodev.wordpress.com",
    hasSupportMe,
 }: PostProps) => ( /* ... */ );


// Class component
class Post3 extends React.Component<PProps, PState> {

    static defaultProps = {
         link: 'https://haodev.wordpress.com'
    }
    
}

Notes: Prop-types

Nói đến việc kiểm tra kiểu dữ liệu của props, phía ReactJS cũng có một built-inprop-types hỗ trợ điều này.

PostI.propTypes = {
    link: PropTypes.string,
    hasSupportMe: PropTypes.boolean.isRequired,
};

PostI.defaultProps = {
    link: "https://haodev.wordpress.com",
    hasSupportMe: true,
};

Chú ý một chút, hasSupportMe được PropTypes khai báo vừa required và vừa có default props, thì React component sẽ hiểu đây chính là Optional props chứ không phải Required props.

Dan Abramov từng có một nhận xét:

React has its own, built-in way of type checking called prop types. Together with TypeScript this provides a full, end-to-end type-checking experience: Compiler and run-time.

Chúng ta hoàn toàn có thể kết hợp sử dụng props-types trong dự án ReactJS tích hợp TypeScript. Chi tiết bạn có thể đọc thêm tại đây.

Hmmm...

Sao lại là "Sử dụng kết hợp"? Chẳng phải chúng đều dùng để check type hay sao?

Nếu đã có prop-types, tại sao vẫn cần dùng Typescript?

Có một số lý do dưới đây:

  • Phân biệt Compiler timeRun time. Về bản chất thì TypeScript cần biên dịch sang JavaScript, trong quá trình biên dịch, nếu việc type check không được đảm bảo, IDEs và ứng dụng sẽ báo lỗi hoặc gợi ý sửa ngay khi chúng ta mắc phải.
  • Chỉ có thể sử dụng prop-types cho các components. Mà trong ứng dụng thì còn muôn vàn các helpers, constants, hooks, common functions không sử dụng React.

Do đó, chúng ta vẫn rất cần anh bạn TypeScript trong trường hợp này ^^

Xuống phần tiếp theo xem TypeScript ứng dụng trong Xử lý sự kiệnStyle - CSS như thế nào nhé!

■ Events

const Post = () => {

    function handleChangeInput(event: SyntheticEvent) { /* ... */ }
   
    function handleClickBtn(event: MouseEvent) { /* ... */ }
  
    return (
        <>
            <input type="text" onChange={handleChangeInput} />
            <button onClick={handleClickBtn}>Comment</button>
        </>
     );
};

Ngoài SyntheticEvent, MouseEvent như ví dụ phía trên, chúng ta có thể tìm hiểu thêm các sự kiện khác như ChangeEvent, ClipboardEvent, DragEvent, FocusEvent, FormEvent, KeyboardEvent, PointerEvent, TouchEvent, etc.

Giả sử chỉ muốn tracking một hoặc một số kiểu element nhất định:

// Chỉ áp dụng cho các HTMLButton Elements
handleVote(event: MouseEvent<HTMLButtonElement>) { /* ... */  }

 // Chỉ áp dụng cho các HTMLButton hoặc HTMLAnchorElement Elements
handleVote(event: MouseEvent<HTMLButtonElement | HTMLAnchorElement>) { /* ... */  }

■ Styles - CSS

Có nhiều cách để áp dụng CSS trong một dự án ReactJS. Do đó việc ứng dụng TypeScript cũng rất đa dạng. Ví dụ với một số phương cách thường gặp:


Với Inline Style

// Declare
import CSS from 'csstype';

const h1Styles: CSS.Properties = {
    fontSize: '1.5rem',
};

// Use
<h1 style={h1Styles}>Make It Awesome</h1>

Với Styled Components

// Declare
type FlexProps = {
  direction?: 'row' | 'column',
}

const Flex = styled.div<FlexProps>`
    display: flex;
    flex-direction: ${props => props.direction};
`;

// Use
const el = <Flex direction="row"></Flex>

Trên đây là một số ví dụ về ứng dụng TypeScript vào ReactJS 😄😄))

Hiển nhiên, một dự án ReactJS không dừng lại ở 01 "chiếc" thư viện ReactJS mà là cả một hệ sinh thái ReactJS với React-Router, Redux, Lodash, Axios, etc. Chưa có gì đáng ngại bởi vì phần lớn chúng đã đều hỗ trợ Typescript đầy đủ (có thể research với từ khoá TECH_NAME + TypeScript). Đôi khi sẽ có một vài thư viện nho nhỏ chưa hỗ trợ Typescript nhưng chúng đều không đáng kể và ít sử dụng.

Eslint cho Typescript cũng gần như không khác gì nhiều; Các IDEs như VSCode, WebStorm, Sublime Text,... cũng hỗ trợ rất tốt ^^

■ Sumup

Yayyy, vậy là chúng ta đã cùng nhau tìm hiểu xong từ lý do chọn TypeScript; thực hành cấu hình cho tới xem qua một số ví dụ cơ bản về việc nhúng TypeScript vào ReactJS rồi nè 🎉🎉

Một điều nữa mình muốn chia sẻ, TypeScript không-sinh-ra-với-mục-đích-thay-thế JavaScript. Nó là một-lựa-chọn.

Với sức mạnh nổi bật của TypeScript, việc tích hợp vào ReactJS sẽ phù hợp với các dự án dài hạn hoặc phục vụ cho việc phát triển một thư viện. Song, nếu chưa chọn dùng TypeScript cũng chẳng sao, TypeScript thực sự tốt nhưng JavaScript không gặp bất lợi gì quá lớn cả, nó vẫn đáng để chúng ta tin tưởng và yêu thích ^^

Các bạn thấy như thế nào, hãy chia sẻ ý kiến của mình phía dưới comment nhé!

Mình cảm ơn các bạn vì đã đọc bài viết này và hy vọng rằng nó có thể mang lại được giá trị nào đó.

Tặng mình 1 upvote để có thêm động lực cho những bài viết sắp tới nha ❤️


Và trong thời điểm hiện tại thì...

Hãy cùng nhau thực hiện quy tắc 5K được Bộ Y tế khuyến cáo:

#Coronavirus #5K #BoY Te
Khẩu trang - Khử khuẩn - Khoảng cách - Không tập trung - Khai báo y tế

để có thể giữ an toàn cho bản thân và mọi người xung quanh nhé 😺😺

Chúc các bạn cuối tuần vui vẻ ^^

■ Credits


Happy coding !


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.