Lời mở đầu
Bài viết này không có mục tiêu cụ thể, nó không phải 1 bài viết hướng dẫn từ A tới Z cho người mới bắt đầu
Nó giống với 1 bài liệt kê các tài liệu liên quan đến Component thì đúng hơn, và hi vọng đâu đó trong bài viết bạn nhặt được 1 phần nào đó bạn chưa biết
Nếu bạn có phần nào không hiểu, đừng ngại để lại 1 Bình Luận cho mình nhé!
1. Component
1 Component sẽ được viết chủ yếu trong [src/features/] và [src/shared/]. Về cơ bản 1 Component sẽ trả về 1 đoạn html.
folder [src/features/] để lưu những Component the từng tính năng, như Login, List, Detail… [src/shared/] lưu những Component được sử dụng nhiều như Header, Footer, Input…
Component có thể là 1 function hoặc là 1 biến lưu 1 callBack funcion đều được.
Tên 1 Component PHẢI bắt đầu bằng chữ in Hoa
Trong Typescript mình hay code như này:
1 2 3 4 5 6 | <span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">interface</span> <span class="token class-name">WelcomeProps</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> string<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token keyword">const</span> Welcome<span class="token operator">:</span> React<span class="token punctuation">.</span><span class="token constant">FC</span> <span class="token operator">=</span> <span class="token punctuation">(</span>props<span class="token operator">:</span> WelcomeProps<span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token operator"><</span>h1<span class="token operator">></span>Hello<span class="token punctuation">,</span> <span class="token punctuation">{</span>props<span class="token punctuation">.</span>name<span class="token punctuation">}</span><span class="token operator"><</span><span class="token operator">/</span>h1<span class="token operator">></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
hoặc rút gọn của callBack function:
1 2 3 | <span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">Welcome</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">props<span class="token operator">:</span> WelcomeProps</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token operator"><</span>h1<span class="token operator">></span>Hello<span class="token punctuation">,</span> <span class="token punctuation">{</span>props<span class="token punctuation">.</span>name<span class="token punctuation">}</span><span class="token operator"><</span><span class="token operator">/</span>h1<span class="token operator">></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">Welcome</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">props<span class="token operator">:</span> WelcomeProps</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token operator"><</span>h1<span class="token operator">></span>Hello<span class="token punctuation">,</span> <span class="token punctuation">{</span>props<span class="token punctuation">.</span>name<span class="token punctuation">}</span><span class="token operator"><</span><span class="token operator">/</span>h1<span class="token operator">></span><span class="token punctuation">;</span> |
Component chỉ cho phép trả về 1 tag, nếu muốn trả về hơn 1 tag thì cần bọc lại bằng 1 thẻ khác, nếu không thể bọc được thì có thể dùng cặp thẻ <></>
. cặp thẻ này sẽ biến mất khi được gen ra code html
2. TypeScript + React: Component patterns
Danh sách này là tập hợp các mẫu Component cho React khi làm việc với TypeScript.
Basic function components
viết Component như 1 function bình thường
1 2 3 4 | <span class="token keyword">function</span> <span class="token function">Title</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token operator"><</span>h1<span class="token operator">></span>Welcome to <span class="token keyword">this</span> application<span class="token operator"><</span><span class="token operator">/</span>h1<span class="token operator">></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Props
được đặt theo tên component + Props-suffix. Không cần sử dụng React.FC
1 2 3 4 5 | type GreetingProps <span class="token operator">=</span> <span class="token punctuation">{</span>name<span class="token operator">:</span> string<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">Greeting</span><span class="token punctuation">(</span><span class="token parameter">props<span class="token operator">:</span> GreetingProps</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token operator"><</span>p<span class="token operator">></span>Hi <span class="token punctuation">{</span>props<span class="token punctuation">.</span>name<span class="token punctuation">}</span> 👋<span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token punctuation">}</span> |
Destructuring
cũng như trên nhưng dễ đọc hơn
1 2 3 4 | <span class="token keyword">function</span> <span class="token function">Greeting</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> name <span class="token punctuation">}</span><span class="token operator">:</span> GreetingProps</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token operator"><</span>p<span class="token operator">></span>Hi <span class="token punctuation">{</span>name<span class="token punctuation">}</span> 👋<span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Default props
phương pháp này cho phép đặt giá trị mặc định cho tham số truyền vào nếu Parent Component không truyền tham số xuống Children
1 2 3 4 5 | type LoginMsgProps <span class="token operator">=</span> <span class="token punctuation">{</span> ame<span class="token operator">?</span><span class="token operator">:</span> string <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">LoginMsg</span><span class="token punctuation">(</span><span class="token punctuation">{</span> name <span class="token operator">=</span> <span class="token string">"Guest"</span> <span class="token punctuation">}</span><span class="token operator">:</span> LoginMsgProps<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token operator"><</span>p<span class="token operator">></span>Logged <span class="token keyword">in</span> <span class="token keyword">as</span> <span class="token punctuation">{</span>name<span class="token punctuation">}</span><span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Children
thay vì dùng FC hay FunctionComponent, chúng ta sẽ set vào [children] type React.ReactNode
vì nó chấp nhận hầu hết (JSX elements, strings, etc.)
1 2 3 4 5 6 7 8 9 10 11 12 13 | type CardProps <span class="token operator">=</span> <span class="token punctuation">{</span> title<span class="token operator">:</span> string<span class="token punctuation">;</span> children<span class="token operator">:</span> React<span class="token punctuation">.</span>ReactNode<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">Card</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> title<span class="token punctuation">,</span> children <span class="token punctuation">}</span><span class="token operator">:</span> CardProps</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span>section className<span class="token operator">=</span><span class="token string">"cards"</span><span class="token operator">></span> <span class="token operator"><</span>h2<span class="token operator">></span><span class="token punctuation">{</span>title<span class="token punctuation">}</span><span class="token operator"><</span><span class="token operator">/</span>h2<span class="token operator">></span> <span class="token punctuation">{</span>children<span class="token punctuation">}</span> <span class="token operator"><</span><span class="token operator">/</span>section<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
cách sử dụng Children trong Parent Component:
1 2 3 4 | <span class="token operator"><</span>Card title<span class="token operator">=</span><span class="token string">"Title"</span><span class="token operator">></span> <span class="token operator"><</span>p<span class="token operator">></span>This is children<span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>Card<span class="token operator">></span> |
Không cho phép Children
thay vì dùng FC hay FunctionComponent, chúng ta sẽ set vào [children] type React.ReactNode
vì nó chấp nhận hầu hết (JSX elements, strings, etc.)
1 2 3 4 5 6 | <span class="token comment">// This throws errors when we pass children</span> type SaveButtonProps <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token comment">//... whatever</span> children<span class="token operator">:</span> never <span class="token punctuation">}</span> |
WithChildren helper type
thay vì dùng FC hay FunctionComponent, chúng ta sẽ set vào [children] type React.ReactNode
vì nó chấp nhận hầu hết (JSX elements, strings, etc.)
1 2 3 | type WithChildren<span class="token operator"><</span><span class="token constant">T</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token operator">></span> <span class="token operator">=</span> <span class="token constant">T</span> <span class="token operator">&</span> <span class="token punctuation">{</span> children<span class="token operator">?</span><span class="token operator">:</span> React<span class="token punctuation">.</span>ReactNode <span class="token punctuation">}</span><span class="token punctuation">;</span> type CardProps <span class="token operator">=</span> WithChildren<span class="token operator"><</span><span class="token punctuation">{</span> title<span class="token operator">:</span> string<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token operator">></span><span class="token punctuation">;</span> |
Điều này rất giống với FC, nhưng với tham số chung mặc định {}, nó có thể linh hoạt hơn nhiều:
1 2 3 | <span class="token comment">// works as well</span> type CardProps <span class="token operator">=</span> <span class="token punctuation">{</span> title<span class="token operator">:</span> string <span class="token punctuation">}</span> <span class="token operator">&</span> WithChildren<span class="token punctuation">;</span> |
Nếu bạn đang sử dụng Preact, bạn có thể sử dụng h.JSX.Elementhoặc VNode dưới dạng một loại thay vì React.ReactNode.
Cá nhân mình nghĩ phần này tác giả đang vẽ rắn thêm chân.
3. cách 1 Component được hiển thị
mặc định file luôn được hiển thị là index.html, mọi thay đổi trong file này sẽ ảnh hưởng tới cả Project. Nhg đây không phải nơi để sửa global trong React, ngta sẽ cố giữ không sửa file này
1 2 3 4 5 | <span class="token operator"><</span>body<span class="token operator">></span> <span class="token operator"><</span>noscript<span class="token operator">></span>You need to enable JavaScript to run <span class="token keyword">this</span> app<span class="token punctuation">.</span><span class="token operator"><</span><span class="token operator">/</span>noscript<span class="token operator">></span> <span class="token operator"><</span>div id<span class="token operator">=</span><span class="token string">"root"</span><span class="token operator">></span><span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>body<span class="token operator">></span> |
bên trong file này sẽ có 1 thẻ: <div id="root"></div>
. đây chính là nơi React thay đổi nội dung html hiển thị
file index.tsx
thay đổi thẻ này bằng các Component thông qua code
1 2 3 4 5 6 | <span class="token keyword">const</span> container <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'root'</span><span class="token punctuation">)</span><span class="token operator">!</span><span class="token punctuation">;</span> <span class="token keyword">const</span> root <span class="token operator">=</span> <span class="token function">createRoot</span><span class="token punctuation">(</span>container<span class="token punctuation">)</span><span class="token punctuation">;</span> root<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span> <span class="token operator"><</span>App <span class="token operator">/</span><span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> |
trong file này có [import ‘./index.css’;], đây là nơi áp dụng 1 số css Global
file App.tsx
cơ bản dùng để phân từng trang tương ứng với Url, thông qua Router
1 2 3 4 5 6 7 8 | <span class="token keyword">const</span> App<span class="token operator">:</span> React<span class="token punctuation">.</span><span class="token function-variable function">FC</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span>div className<span class="token operator">=</span><span class="token string">"App"</span><span class="token operator">></span> <span class="token operator"><</span>Router <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
file Router.tsx
thường áp dụng với Extenstion react-router, hoặc phân trang bằng tay
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <span class="token keyword">const</span> Router<span class="token operator">:</span> React<span class="token punctuation">.</span><span class="token function-variable function">FC</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span>BrowserRouter<span class="token operator">></span> <span class="token operator"><</span>HeaderComponent <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span>Routes<span class="token operator">></span> <span class="token operator"><</span>Route path<span class="token operator">=</span><span class="token punctuation">{</span><span class="token constant">URL_PATH</span><span class="token punctuation">.</span><span class="token constant">LIST</span><span class="token punctuation">}</span> element<span class="token operator">=</span><span class="token punctuation">{</span> <span class="token operator"><</span>ListComponent <span class="token operator">/</span><span class="token operator">></span> <span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span>Route path<span class="token operator">=</span><span class="token punctuation">{</span><span class="token constant">URL_PATH</span><span class="token punctuation">.</span><span class="token constant">DATA1</span><span class="token punctuation">}</span> element<span class="token operator">=</span><span class="token punctuation">{</span> <span class="token operator"><</span>Data1Component <span class="token operator">/</span><span class="token operator">></span> <span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span>Route path<span class="token operator">=</span><span class="token punctuation">{</span><span class="token constant">URL_PATH</span><span class="token punctuation">.</span><span class="token constant">DATA2</span><span class="token punctuation">}</span> element<span class="token operator">=</span><span class="token punctuation">{</span> <span class="token operator"><</span>Data2Component <span class="token operator">/</span><span class="token operator">></span> <span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span>Route path<span class="token operator">=</span><span class="token punctuation">{</span><span class="token constant">URL_PATH</span><span class="token punctuation">.</span><span class="token constant">CONFIRM</span><span class="token punctuation">}</span> element<span class="token operator">=</span><span class="token punctuation">{</span> <span class="token operator"><</span>ConfirmComponent <span class="token operator">/</span><span class="token operator">></span> <span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span>Route path<span class="token operator">=</span><span class="token punctuation">{</span><span class="token constant">URL_PATH</span><span class="token punctuation">.</span><span class="token constant">DETAIL</span><span class="token punctuation">}</span> element<span class="token operator">=</span><span class="token punctuation">{</span> <span class="token operator"><</span>DetailComponent <span class="token operator">/</span><span class="token operator">></span> <span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span>Route path<span class="token operator">=</span><span class="token punctuation">{</span><span class="token constant">URL_PATH</span><span class="token punctuation">.</span><span class="token constant">INDEX</span><span class="token punctuation">}</span> element<span class="token operator">=</span><span class="token punctuation">{</span> <span class="token operator"><</span>LoginComponent <span class="token operator">/</span><span class="token operator">></span> <span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span>Route path<span class="token operator">=</span><span class="token punctuation">{</span><span class="token constant">URL_PATH</span><span class="token punctuation">.</span><span class="token constant">LOGIN</span><span class="token punctuation">}</span> element<span class="token operator">=</span><span class="token punctuation">{</span> <span class="token operator"><</span>LoginComponent <span class="token operator">/</span><span class="token operator">></span> <span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span>Route path<span class="token operator">=</span><span class="token punctuation">{</span><span class="token constant">URL_PATH</span><span class="token punctuation">.</span><span class="token constant">NOT_FOUND</span><span class="token punctuation">}</span> element<span class="token operator">=</span><span class="token punctuation">{</span> <span class="token operator"><</span>InvalidComponent <span class="token operator">/</span><span class="token operator">></span> <span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>Routes<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>BrowserRouter<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
tuy nhiên mỗi Component không phải là 1 Page, Component có thể nhỏ như 1 cái Button, 1 Area hay to như file App.tsx cũng là 1 Component