Xin chào các bạn. Dạo gần đây, nhà nhà người người đều đổ xô đi học React. Mình cũng tò mò tại sao react hot đến vậy nên vô docs và bắt đầu thử sức luôn.
Tìm hiểu được 1 thời gian thì các anh GL có tổ chức training và làm 1 project để demo. Không có gì đáng nói nếu như mình không gặp một số bugs củ chuối. Báo lỗi lại lung tung nên mình không biết đâu mà lần @@
Có bugs mình tìm hiểu mất gần buổi sáng. Bực quá, chỉ vì truyền props bị sai kiểu. Lúc đó nhờ có ông anh ngồi ngay đằng sau để xin chỉ giáo mà mình biết được react có 1 package là prop-types để validate đống props và vả vào mặt mình 1 cái báo lỗi để mình chỉnh sửa lại props cho đúng. Nói thế thôi chứ mình thích package này lắm, đỡ phải ăn hành bởi đống bugs ngớ ngẩn do truyền sai props. Nếu các bạn chuyển từ C#, C hay Java sang Js thì đúng là khó chịu lắm với kiểu khai báo biến mà không có kiểu dữ liệu. Chính từ đó mà khi dùng biến đó ở chỗ khác thì mình không còn nhận ra nó thuộc kiểu nào nữa. Trong React thì còn bị lãng quên nhiều hơn khi truyền qua props của hàng đống components. Cùng mình tìm hiểu nhé.
Cách thêm typechecking cho components
Thực sự dễ luôn các ông ạ, giả sử các ông có data như này nhé (hình dưới)
ô tô kê, giờ có 2 file như này ListPets.js và Pet.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span> Component <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Pet <span class="token keyword">from</span> <span class="token string">'./Pet'</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">MyPets</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span> state <span class="token operator">=</span> <span class="token punctuation">{</span> pets<span class="token punctuation">:</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span>id<span class="token punctuation">:</span><span class="token number">1</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">'fluffy'</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token string">'white'</span><span class="token punctuation">,</span> age<span class="token punctuation">:</span> <span class="token number">6</span><span class="token punctuation">,</span> type<span class="token punctuation">:</span> <span class="token string">'dog'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>id<span class="token punctuation">:</span><span class="token number">2</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">'molly'</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token string">'brown'</span><span class="token punctuation">,</span> age<span class="token punctuation">:</span> <span class="token number">9</span><span class="token punctuation">,</span> type<span class="token punctuation">:</span> <span class="token string">'cat'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>id<span class="token punctuation">:</span><span class="token number">3</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">'buster'</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token string">'black'</span><span class="token punctuation">,</span> age<span class="token punctuation">:</span> <span class="token number">3</span><span class="token punctuation">,</span> type<span class="token punctuation">:</span> <span class="token string">'dog'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>id<span class="token punctuation">:</span><span class="token number">4</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">'grant'</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token string">'black'</span><span class="token punctuation">,</span> age<span class="token punctuation">:</span> <span class="token number">6</span><span class="token punctuation">,</span> type<span class="token punctuation">:</span> <span class="token string">'cat'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>id<span class="token punctuation">:</span><span class="token number">5</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">'pepsi'</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token string">'grey'</span><span class="token punctuation">,</span> age<span class="token punctuation">:</span> <span class="token number">4</span><span class="token punctuation">,</span> type<span class="token punctuation">:</span> <span class="token string">'dog'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>id<span class="token punctuation">:</span><span class="token number">6</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">'winston'</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token string">'brown'</span><span class="token punctuation">,</span> age<span class="token punctuation">:</span> <span class="token number">8</span><span class="token punctuation">,</span> type<span class="token punctuation">:</span> <span class="token string">'dog'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>id<span class="token punctuation">:</span><span class="token number">7</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">'sprite'</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token string">'white'</span><span class="token punctuation">,</span> age<span class="token punctuation">:</span> <span class="token number">10</span><span class="token punctuation">,</span> type<span class="token punctuation">:</span> <span class="token string">'cat'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>id<span class="token punctuation">:</span><span class="token number">8</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">'oscar'</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token string">'grey'</span><span class="token punctuation">,</span> age<span class="token punctuation">:</span> <span class="token number">2</span><span class="token punctuation">,</span> type<span class="token punctuation">:</span> <span class="token string">'dog'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>id<span class="token punctuation">:</span><span class="token number">9</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">'bumper'</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token string">'black'</span><span class="token punctuation">,</span> age<span class="token punctuation">:</span> <span class="token number">12</span><span class="token punctuation">,</span> type<span class="token punctuation">:</span> <span class="token string">'dog'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>id<span class="token punctuation">:</span><span class="token number">10</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">'happy'</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token string">'white'</span><span class="token punctuation">,</span> age<span class="token punctuation">:</span> <span class="token number">11</span><span class="token punctuation">,</span> type<span class="token punctuation">:</span> <span class="token string">'dog'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>id<span class="token punctuation">:</span><span class="token number">11</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">'speedy'</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token string">'black'</span><span class="token punctuation">,</span> age<span class="token punctuation">:</span> <span class="token number">9</span><span class="token punctuation">,</span> type<span class="token punctuation">:</span> <span class="token string">'cat'</span> <span class="token punctuation">}</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> title<span class="token punctuation">:</span> <span class="token string">'my pets'</span> <span class="token punctuation">}</span> <span class="token function">render</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 punctuation">(</span> <span class="token operator"><</span>div<span class="token operator">></span> <span class="token operator"><</span>h2<span class="token operator">></span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<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 operator"><</span>ul<span class="token operator">></span> <span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>pets<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>pet <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token operator"><</span>Pet key<span class="token operator">=</span><span class="token punctuation">{</span>pet<span class="token punctuation">.</span>id<span class="token punctuation">}</span> pet<span class="token operator">=</span><span class="token punctuation">{</span>pet<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span> <span class="token operator"><</span><span class="token operator">/</span>ul<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><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token keyword">default</span> MyPets |
1 2 3 4 5 6 7 8 9 10 11 | <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 comment">//functional stateless component</span> <span class="token keyword">const</span> <span class="token function-variable function">Pet</span> <span class="token operator">=</span> <span class="token punctuation">(</span>props<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>li<span class="token operator">></span><span class="token punctuation">{</span><span class="token template-string"><span class="token string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>props<span class="token punctuation">.</span>pet<span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> is </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>props<span class="token punctuation">.</span>pet<span class="token punctuation">.</span>color<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> and is </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>props<span class="token punctuation">.</span>pet<span class="token punctuation">.</span>age<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> years old.`</span></span><span class="token punctuation">}</span><span class="token operator"><</span><span class="token operator">/</span>li<span class="token operator">></span> <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">default</span> Pet |
Kịch bản đơn giản là ListPet sẽ truyền props qua Pet để hiển thị tương ứng với dữ liệu.
Giờ nếu tôi chỉnh sửa dòng 29 của file ListPets thành
1 2 | <span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>pets<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>pet <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token operator"><</span>Pet key<span class="token operator">=</span><span class="token punctuation">{</span>pet<span class="token punctuation">.</span>id<span class="token punctuation">}</span> pet<span class="token operator">=</span><span class="token punctuation">{</span>pet<span class="token punctuation">.</span>name<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span> |
âu sít, ta sẽ gặp 1 bugs kiểu như này:
ListPets: tôi truyền đủ props rồi nhé, ông hiển thị đi nhá
Pet: tui cần 1 object, cơ, ông truyền cái gì thế tui không hiểu
Rồi luôn. Lúc mình gặp lỗi này mình sẽ nghĩ: ơ mình truyền đúng mà.
Vâng đúng cái beep. Underfind 1 núi :v
Cơ mà đáng nói là bật console lên thì lại méo thấy lỗi, huhu giờ sao. Báo lỗi mới biết sửa chứ nhỉ.
Lúc này chúng ta cần 1 dòng báo lỗi là mọi chuyện ez ngay. Cảm cúm có tiffy thì validate props có prop-types
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <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">import</span> PropTypes <span class="token keyword">from</span> <span class="token string">'prop-types'</span><span class="token punctuation">;</span> <span class="token comment">//functional stateless component</span> <span class="token keyword">const</span> <span class="token function-variable function">Pet</span> <span class="token operator">=</span> <span class="token punctuation">(</span>props<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>li<span class="token operator">></span><span class="token punctuation">{</span><span class="token template-string"><span class="token string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>props<span class="token punctuation">.</span>pet<span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> is </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>props<span class="token punctuation">.</span>pet<span class="token punctuation">.</span>color<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> and is </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>props<span class="token punctuation">.</span>pet<span class="token punctuation">.</span>age<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> years old.`</span></span><span class="token punctuation">}</span><span class="token operator"><</span><span class="token operator">/</span>li<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// setup typechecking </span> Pet<span class="token punctuation">.</span>propTypes <span class="token operator">=</span> <span class="token punctuation">{</span> pet<span class="token punctuation">:</span> PropTypes<span class="token punctuation">.</span>object <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> Pet |
Với 1 đoạn setup trên thì khi gọi component Pet, nó sẽ vả ngay cho chúng ta 1 dòng báo lỗi khi truyền sai props như sau:
Okay, và thế là ta đã có thể nhận ra sự bất cẩn khi truyền sai props.
Giờ ta sửa lại cho đúng props mà component Pet mong muốn là ta sẽ có danh sách Pets yêu quý của ta hiện lên
Tổng kết
- Javascript là ngôn ngữ không cung cấp định kiểu dữ liệu
- Prop-types là 1 cách đơn giản để giảm thiểu lỗi truyền sai dữ liệu.
- Với Prop-types, ta sẽ biết ngay Component con cần loại dữ liệu nào để hiển thị đúng.
- Đừng quên import thư viện trước khi dùng nhé :v
Các bạn có thể đọc thêm ở docs nhá https://reactjs.org/docs/typechecking-with-proptypes.html
# Tham khảo
https://medium.com/dailyjs/how-to-add-typechecking-to-your-react-components-223c5560ba58