Chia sẽ kinh nghiệm để hiểu về Lifecycle trong React Native

volamfan

Support
Moderator
Chào mọi người, năm nay mình đã đi làm được năm thứ 3, trong đó có 1 năm là native Android và 1.5 năm React Native (RN), nên cũng có 1 số kinh nghiệm cơ bản mình tự rút được sau gần 3 năm đó muốn share lại với mọi người, đặc biệt là các bạn mới (Mình bỏ qua mấy cái như làm sao cài đặt, init app này nọ, vì trên Google đã có hết rồi. Mình sẽ bắt đầu từ lúc các bạn đã chạy được ”Hello World” trên RN, và có kỹ năng search Google rồi nhé).

1. Khi bạn mới bắt đầu, bạn nên nắm rõ vấn đề gì?

Lifecycle là thứ mà bạn nên nắm rõ khi bắt đầu 1 dự án. Khi run project, bạn phải biết đoạn code nào được chạy đầu tiên. Khi setState, props thay đổi, thì đến lượt thằng nào sẽ được gọi.
Tại sao phải nắm rõ về lifecycle của React? Vì đây chính là yếu tố ảnh hưởng rất lớn về performance của app, nếu xử lý ko tốt, sẽ dẫn đến việc re-render không cần thiết, từ đó khiến cho app của bạn chậm, lag, crash.
Dưới đây là kinh nghiệm xử lý lifecycle của mình:
  • constructor(): đây là thằng được gọi đầu tiên, tại đây chỉ nên init 1 số state để xài, không nên để function vô đây.
  • render() - lần 1: đây là lúc mà component của bạn được vẽ ra. Lúc này nếu chưa có data thì cứ quăng cái <Loading/> vào, khi nào có data thì mới re-render để hiện UI. Mình nghĩ là sẽ có nhiều bạn sẽ tìm cách lấy hết data trước rồi mới render UI, việc đó không cần thiết vì mới vô app hiện <Loading/> ngay nó sẽ tốt hơn là vô app màn hình trắng bóc, đợi 1 hồi mới có UI.
  • componentDidMount(): lúc này thì bạn có thể bắt đầu gọi api này nọ, thực hiện function trong đây.
  • shouldComponentUpdate(): không nên bỏ qua thằng này, khi setState hoặc reducer trong Redux thay đổi (mà component của bạn có đang xài reducer đó - mapStateToProps) thì nó sẽ được gọi, đây chính là nơi giảm thiếu tối đa vấn đề re-render dư thừa, khi nào cần thì mới re-render thôi.
  • render() - lần 2: nếu bạn có gọi API và lưu data response vào reducer hoặc setState ở componentDidMount, và shouldComponentUpdate() return true, render sẽ được gọi lần 2, lúc này bạn đã có đủ data để show UI cho user thay cho cái <Loading/> ban đầu rồi.
  • componentDidUpdate(): đứa này mình ít dùng nhất, sau khi render xong, nó sẽ vô đây, còn xài như thế nào thì tùy kinh nghiệm mỗi người. (update thêm) Sau khi nhận được response từ server, nếu thanh công hoặc bị lỗi bạn có thể thông báo cho user tại đây. (VD: setState show Modal thông báo Thành công hoặc Có lỗi xảy ra)
  • componentWillUnmount(): gọi trước khi component của bạn bị remove khỏi stack, ở đây mình thường remove mấy cái event listener hoặc clear data thôi.
==> Bạn thấy đấy, nếu đúng theo lifecycle của mình, thì từ lúc component được gọi đến khi nó hiện ra, mình chỉ render 2 lần: lần 1 hiện loading đợi data, lần 2 hiện UI khi có data.
Tips: Bạn đặt log ở render(), nếu nó được gọi đến 4-5 lần thì nên kiểm tra lại có set state lung tung hay không.

2. Expo, nên hay không?

Xài Expo cho vui thôi, khi đã nghiêm túc làm 1 dự án thì nên xài React Native CLI. Vì, bạn sẽ không biết trước được dự án mình làm sẽ lớn đến đâu, cần thêm những thư viên nào dính đến code native, Expo không thể install thêm thư viện native nên sẽ hạn chế việc mở rộng dự án của bạn, và có nhiều thư viện không xài đến dẫn đến cái app của bạn nặng hơn. (Xem thêm ý kiến khác ở comment)

3. Có nên sử dụng React Hooks?

Có khi bạn đã nắm rõ về lifecycle, vì React Hooks sẽ tối giản được code của bạn rất nhiều. Code ngắn hơn, dễ nhìn hơn, dễ hiểu hơn. Nhưng nếu bạn chưa nắm được lifecycle của RN thì việc bắt đầu với Hooks sẽ hơi khó. 1 file js nên giới hạn 200-300 dòng thôi, chứ 500 dòng trở lên là hết muốn đọc, tìm code cũng mệt nữa.

4. Con đường từ class component đến function component của mình:

Lúc bắt đầu dự án, mình vẫn chưa tìm hiểu đến React Hooks, nên vẫn xài class component. Sau khi tìm hiểu và muốn áp dụng Hooks vào dự án đó, mình đã trộn 2 cái vào nhau.
Tức là thế này, về cái bự nhất (screen) thì mình dùng class component như trước, nhưng component con ở trong, mình sử dụng 100% function component. Ban đầu, mình sử dụng function component cho những thằng nào ko có state để làm quen trước, sau đó mới dần xài thêm useState, và cuối cùng là xài Hooks cho cả project mới.

5. Có nên sử dụng thư viện hay không?

Mình chỉ có thể nói không nên quá lạm dụng đến thư viện.
Mình gặp nhiều bạn, hỏi cái này, cái kia có libs không, trong khi cái đó hoàn toàn có thể tự code được. Lợi thế của việc tự code là tăng thêm kinh nghiệm, biết được lúc nào nên tách ra component để tái sử dụng. Lúc đó mấy file js của bạn sẽ gọn hơn nữa (200-300 dòng như mình đã nói ở trên).
Gặp 1 UI mà mình chưa code qua, đầu tiên là “tự code”, nếu bí quá rồi, tìm đến thư viện thì chọn lọc cái mình cần, vì thư viện nhiều khi có 10 nhưng cái mình cần chỉ là 1.
Khi bạn đã tách component ra thì nên code sao cho có khả năng “mở rộng”. VD: 1 cái component Button, mà bạn hardcode width height color luôn thì thua, lúc này {…props} giúp được bạn.
Quan trọng nhất trong việc tự viết component là phải biết được INPUT và OUTPUT của component đó. (Đọc vào thì có vẻ dễ, nhưng để làm được thì mình đã tốn kha khá thời gian, và trả qua biết bao nhiêu dự án)

Trên đây là 1 số kinh nghiệm cơ bản về RN mà mình muốn chia sẻ, còn nhiều cái lẻ tẻ mà mình không gom lại được. Ngoài việc chia sẻ, mình cũng mong muốn nhận lại góp ý từ mọi người để học hỏi thêm kinh nghiệm.
 
Top