React
React là gì
React là một thư viện JavaScript mã nguồn mở và giao diện người dùng, rất hữu ích trong việc phát triển giao diện người dùng dành riêng cho các ứng dụng SPA. Nó hữu ích trong việc xây dựng các thành phần giao diện người dùng (UI) phức tạp và có thể tái sử dụng của các ứng dụng web và di động vì nó tuân theo mô hình dựa trên component.
Tính năng của React:
Tăng hiệu suất của ứng dụng với Virtual DOM.
JSX làm cho code dễ đọc và viết.
Nó kết xuất cả phía máy khách và máy chủ.
Dễ dàng tích hợp với các frameworks khác (Angular, BackboneJS) vì nó chỉ là một thư viện giao diện.
Dễ dàng viết các trường hợp kiểm thử UI và tích hợp với các công cụ như JEST.
Lợi ích khi dùng React
ReactJS giúp cho việc viết các đoạn code Javascript sẽ trở nên dễ dàng hơn vì nó sử dụng một cú pháp đặc biệt đó chính là cú pháp JSX. Thông qua JSX cho phép nhúng code HTML và Javascript.
ReactJS cho phép nhà phát triển phá vỡ những cấu trúc UI phức tạp thành những component độc lập. Các nhà phát triển sẽ không phải lo lắng về tổng thể ứng dụng web, giờ đây có thể dễ dàng chia nhỏ các cấu trúc UI/UX phức tạp thành từng component đơn giản hơn.
Do sử dụng các component nên React có tính tái sử dụng cao
Đi kèm với ReactJS là rất nhiều các công cụ phát triển giúp cho việc debug code một cách dễ dàng hơn.
Một trong những ưu điểm nữa của ReactJS đó là sự thân thiện với SEO. Hầu như các JS Frameworks không thân thiện với các tìm kiếm mặc dù đã được cải thiện nhiều nhưng dưới sự hỗ trợ của các render dữ liệu trả về dưới dạng web page giúp cho SEO chuẩn hơn.
React cùng với React Native, Redux, Electro cùng với nhiều công cụ hữu ích khác giúp nhà phát triển xây dựng được đa dạng loại ứng dụng phù hợp với nhiều yêu cầu.
Hạn chế của React
React không phải một framework hoàn chỉnh mà chỉ là thư viện.
Component trong React sẽ rất nhiều và mất nhiều thời gian để hiểu với các trang web phức tạp.
Code sẽ trở nên phức tạp khi dùng template với JSX.
Khá khó cho người mới bắt đầu.
Sự khác biệt giữa class component và function component
Trước khi giới thiệu hooks ở phiên bản 16, các function component được gọi là stateless component và ít khi được dùng trong React. Sau khi hook ra đời, các function component giờ đã ngang hàng với class component.
Khai báo
Function component giống như một hàm thông thường trong JS, ta có thể tạo kiểu arrow function hoặc function:
Class component sử dụng cú pháp tạo lớp của ES6
Xử lý props
Ta thử render component dưới đây theo cả hai cách:
Trong function component, xử lý props rất thẳng thắn. Bất ký props nào cũng được xem như tham số của function component có thể xử lý trực tiếp:
Với class component, props được xử lý bằng this
:
Xử lý state
Function component sử dụng hook để quản lý state. Hook hữu ích nhất là useState
cho thiết lập state trong component.
Ta không thể sử dụng hook bên trong class component, thế nên ta vẫn phải xử lý state bằng this
trong class component.
Virtual DOM
Virtual DOM là một khái niệm trong đó biểu diễn ảo của DOM thực được lưu giữ bên trong bộ nhớ và được đồng bộ hóa với DOM thực bởi một thư viện như ReactDOM
Tại sao cần Virtual DOM
Thao tác DOM là một phần không thể thiếu của bất kỳ ứng dụng web nào, nhưng thao tác DOM khá chậm khi so sánh với các thao tác khác trong JavaScript. Hiệu quả của ứng dụng bị ảnh hưởng khi một số thao tác DOM đang được thực hiện. Hầu hết các framework JavaScript cập nhật toàn bộ DOM ngay cả khi một phần nhỏ của DOM thay đổi.
Ví dụ: hãy xem xét một danh sách đang được hiển thị bên trong DOM. Nếu một trong các mục trong danh sách thay đổi, toàn bộ danh sách sẽ được hiển thị lại thay vì chỉ hiển thị mục đã được thay đổi/cập nhật. Đây được gọi là cập nhật không hiệu quả.
Để giải quyết vấn đề cập nhật không hiệu quả, team React đã đưa ra khái niệm virtual DOM
Đối với mỗi đối tượng DOM, có một đối tượng DOM ảo tương ứng (bản sao), có các thuộc tính giống nhau. Sự khác biệt chính giữa đối tượng DOM thực và đối tượng DOM ảo là bất kỳ thay đổi nào trong đối tượng DOM ảo sẽ không phản ánh trực tiếp trên màn hình. Hãy coi một đối tượng DOM ảo như một bản thiết kế của đối tượng DOM thực. Bất cứ khi nào một phần tử JSX được hiển thị, mọi đối tượng DOM ảo sẽ được cập nhật.
Lưu ý- Người ta có thể nghĩ rằng việc cập nhật mọi đối tượng DOM ảo có thể không hiệu quả, nhưng không phải vậy. Cập nhật DOM ảo nhanh hơn nhiều so với cập nhật DOM thực vì chúng tôi chỉ cập nhật bản thiết kế của DOM thực.
React sử dụng hai virtual DOM để hiển thị giao diện người dùng. Một cái được sử dụng để lưu trữ trạng thái hiện tại của các đối tượng và cái còn lại để lưu trữ trạng thái trước đó của các đối tượng. Bất cứ khi nào DOM ảo được cập nhật, React so sánh hai DOM ảo và biết về đối tượng DOM ảo nào đã được cập nhật. Sau khi biết đối tượng nào đã được cập nhật, React chỉ hiển thị các đối tượng đó bên trong DOM thực thay vì hiển thị DOM thực hoàn chỉnh. Bằng cách này, với việc sử dụng virtual DOM, react sẽ giải quyết được vấn đề cập nhật không hiệu quả.
Giải thích state và props
Bất biến
Có thể thay đổi
Hiệu suất tốt hơn
Phạm vi cục bộ
Truyền được cho component khác
Truyền được giống như props
Có phương thức setState để đổi giá trị
Đổi trạng bất đồng bộ
Các kiểu side effect trong React component
Có hai kiểu side effect trong React.
Effect không có cleanup: Side effect này sẽ được sử dụng trong
useEffect
không hạn chế trình duyệt cập nhật màn hình. Nó cũng cải thiện khả năng phản hồi của một ứng dụng. Một vài ví dụ phổ biến là yêu cầu mạng, logging, chỉnh sửa DOM thủ công, v.v.Effect có cleanup: Một số Hook effect sẽ yêu cầu cleanup sau khi cập nhật xong DOM. Ví dụ: nếu bạn muốn thiết lập đăng ký nguồn dữ liệu bên ngoài, nó yêu cầu dọn dẹp bộ nhớ, nếu không có thể xảy ra sự cố rò rỉ bộ nhớ. Có một thực tế là React sẽ thực hiện dọn dẹp bộ nhớ khi các component unmounting. Nhưng các effect sẽ chạy mỗi phương thức
render()
hơn là cho bất kỳ phương thức cụ thể nào. Do đó, chúng ta có thể nói rằng, trước khi thực thi các hiệu ứng thời gian, React cũng sẽ dọn dẹp các hiệu ứng từ lần hiển thị trước đó.
Các quy tắc sử dụng React Hooks
Chỉ có thể gọi hooks trong function component (không thể dùng trong class).
Chỉ có thể gọi ở cấp cao, không thể gọi trong hàm, vòng lặp hay điều kiện.
Các cách khác nhau để chỉnh style component
Inline Styling: ta có thể chỉnh style trực tiếp lên phần tử bằng cách dùng thuộc tính style
. Nhớ giá trị của style
luôn là đối tượng JavaScript:
Javascript Object: ta có thể tạo đối tượng JavaScript và tập mô tả thuộc tính style. Các đối tượng có thể dùng như giá trị của thuộc tính style.
CSS Stylesheet: Ta sẽ tạo một file CSS riêng và viết tất cả style cho component trong file đó. Sau đó import nó vào file React.
CSS Module: Tương tự như file CSS, nhưng ta sửa thành .module.css
, với cách này tên lớp sẽ được mã hoá, đồng thời nó hỗ trợ kiểu viết tương tự sass.
Ta có thể import file vào component như sau:
Các kỹ thuật tối ưu hiệu suất ứng dụng React
useMemo()
Là hook dùng cho caching CPU.
Đôi khi trong các ứng dụng web, các hàm đắt (tính toán nhiều, tốn bộ nhớ) được gọi liên túc do re-render đẫn đến tốc độ render chậm, hiệu suất kém.
useMemo() có thể sử dụng cho cache cám hàm như vậy. Bằng cách dùng useMemo() các hàm đó chỉ được gọi khi cần thiết.
React.PureComponent
Là class component cơ sở để kiểm tra state và props của một component để biết khi nào nó nên được cập nhật.
Thay vì dùng React.Component, ta có sử dụng React.PureComponent để giảm việc re-render không cần thiết.
Duy trì vị trí state
Đây là quá trình chuyển state đến nơi bạn nhất có thể.
Thỉnh thoảng ta có các state không cần thiết nằm trong component cha để gây khó đọc và bảo trì hơn, thậm chí là dẫn đến re-render không cần thiết.
Để tốt hơn, ta chuyển các state vô nghĩa ở component cha sang một component riêng biệt.
Lazy Loading
Đây là kỹ thuật dùng để giảm thời gian tải của ứng dụng React. Lazy loading giúp tối ưu hiệu suất ứng dụng web bằng cách chỉ tải khi cần thiết.
Các giai đoạn trong vòng đời component
Có 3 giai đoạn trong vòng đời component React.
Mounting: đề cập đến việc đưa phần tử vào DOM của trình duyệt. Vì React dùng virtual DOM, toàn bộ DOM của trình duyệt đã render sẽ không được làm mới. Bao gồm các phương thức trong giai đoạn này bao gồm:
constructor
vàcomponentDidMount
.Updating: Trong giai đoạn này, component sẽ được cập nhật khi có thay đổi state hoặc props của component. Các phương thức trong giai đoạn này:
getDerivedStateFromProps
,shouldComponentUpdate
,render
, vàcomponentDidUpdate
.Unmounting: Ở giai đoạn cuối, component sẽ bị xoá khỏi DOM. Giai đoạn này sẽ có phương thức là
componentWillUnmount
.
Các phương thức trong vòng đời component
Trong vòng đời của React sẽ có các phương thức sẽ được gọi tự động ở các giai đoạn khác nhau trong vòng đời của component và do đó nó cung cấp khả năng kiểm soát tốt những gì xảy ra tại điểm được gọi. Nó cung cấp năng lực để kiểm soát và thao tác hiệu quả những gì diễn ra trong suốt vòng đời của component.
Ví dụ: nếu bạn đang phát triển ứng dụng YouTube, thì ứng dụng sẽ sử dụng mạng để đệm video và nó tiêu tốn pin (giả sử chỉ có hai mạng này). Sau khi phát video, nếu người dùng chuyển sang bất kỳ ứng dụng nào khác, thì bạn nên đảm bảo rằng các tài nguyên như mạng và pin đang được sử dụng hiệu quả nhất. Bạn có thể dừng hoặc tạm dừng tải video vào bộ đệm, do đó sẽ ngừng sử dụng pin và mạng khi người dùng chuyển sang ứng dụng khác sau khi phát video.
Vì vậy, chúng ta có thể nói rằng nhà phát triển sẽ có thể tạo ra một ứng dụng chất lượng với sự trợ giúp của các phương pháp vòng đời và nó cũng giúp các nhà phát triển đảm bảo lập kế hoạch những gì và làm như thế nào tại các thời điểm sinh, phát triển hoặc chết của giao diện người dùng.
Các phương thức trong vòng đời:
constructor()
: phương thức được gọi khi component được tạo trước khi thực hiện bất kỳ hành động gì. Nó giúp tạo state và props.getDerivedStateFromProps()
: nó sẽ gọi trước khi phần tử được render vào DOM. Nó giúp thiết lập đối tượng state dựa trên props khởi tạo. Phương thứcgetDerivedStateFromProps
sẽ có một state như đối số và trả về một đối tượng để thay đổi state. Nó sẽ là phương thức đầu tiên được gọi khi thực hiện cập nhật.render()
: phương thức này sẽ render HTML từ DOM với thay đổi mới nhất. Phương thứcrender
sẽ được gọi mỗi khi có thay đổi đến component.componentDidMount()
: phương thức sẽ được gọi sau khi render component. Ta có thể chạy lệnh cần component đã được lưu trong DOM.shouldComponentUpdate()
: trả về giá trị boolean để quyết định xem có render hay không. Mặc định sẽ là True.getSnapshotBeforeUpdate()
: cung cáp truy cập cho props cung như state trước khi cập nhật. Nó dùng cho kiểm tra giá trị trước khi cập nhật.componentDidUpdate()
: được gọi sau khi cập nhật component trong DOM.componentWillUnmount()
: phương thức được gọi khi component bị xoá khỏi DOM.
Các kiểu Hooks trong React
Hook có sẵn: là các hooks được hỗ trợ sẵn trong React
Hook cơ bản:
useState()
: là component dùng cho thiết lập và chỉnh sửa state.useEffect()
: cho phép thực hiện side effect trên function component.useContext()
: dùng cho tạo dữ liệu chung có thể truy cập trong hệ phân cấp component mà không cần truyền dữ liệu theo props từ trên xuống.
Hook nâng cao:
useReducer()
: dùng cho các logic state phức tạp có nhiều giá trị con khi cập nhật state phụ thuộc vào state trước đó. Nó sẽ giúp tối ưu hoá hiệu suất component khi kích hoạt các bản cập nhật sâu hơn vì nó được truyền xuống thay vì callback.useMemo()
: điều này sẽ được sử dụng để tính toán lại giá trị đã ghi nhớ khi có sự thay đổi trong một trong các phần phụ thuộc. Việc tối ưu hóa này sẽ giúp tránh các tính toán tốn kém trên mỗi lần render.useCallback()
: hữu ích khi truyền callback vào component con đã tối ưu hoá và phụ thuộc vào tham chiếu để ngăn chặn các render không cần thiết.useImperativeHandle()
: cho phép chỉnh sửa thực thể sẽ được truyền cho đối tượng ref.useDebugValue()
: dùng cho hiển thị nhãn hoặc hook tuỳ chỉnh trong React DevTools.useRef()
: Nó sẽ cho phép tạo một tham chiếu đến phần tử DOM trực tiếp trong function component.useLayoutEffect()
: dùng cho đọc bố cục từ DOM và re-render bất đồng bộ.
Hook tuỳ chỉnh: là một hàm JavaScript. Hoạt động giống như một hàm thông thường với "use" phía trước để React hiểu đó là một hook tuỳ chỉnh và sẽ mô tả các hàm đặc biệt theo quy tắc của Hook. Hơn thế nữa, việc phát triển hook tuỳ chỉnh cho phép bạn trích xuất logic component trong các hàm có thể tái sử dụng
Sự khác biệt giữa lớp và React Hook
Được dùng cho function component
Được dùng cho class component
Không yêu cầu khai báo constructor
Cần constructor trong các class component
Không yêu cầu con trỏ this cho khai báo hay chỉnh sửa
Cần dùng this cho khai báo state (this.state) và chỉnh sửa (this.setState())
Dễ sử dụng với useState
Không có hàm cụ thể giúp ta truy cập state với setState tương ứng
Hữu dụng khi triển khai Redux và Context API
Quá trình thiết lập state lâu, nên class state sẽ không được ưu tiên
Hiệu suất của React Hook so với lớp
React Hooks sẽ tránh được rất nhiều chi phí như tạo thực thể, liên kết các sự kiện, .., có trong các lớp.
Các hook trong React sẽ dẫn đến các cây component nhỏ hơn vì chúng sẽ tránh được việc lồng nhau tồn tại trong HOC và sẽ render props dẫn đến việc React phải thực hiện ít công việc hơn
Hook có thay thế được lớp hoàn toàn
Mục đích của Hook là thay thế các chức năng được cung cấp bởi lớp. Nhưng có các phương thức mà Hook vẫn chưa thay thế được lớp:
getSnapshotBeforeUpdate()
getDerivedStateFromError()
componentDidCatch()
Axios
Axios là một promise dựa trên HTTP để tạo yêu cầu HTTP đến trình duyệt hay web server.
Tính năng
Interceptors: Truy cập cấu hình yêu cầu hoặc phản hồi (header, dữ liệu, v.v.) khi chúng gửi đến hoặc đi. Các hàm này có thể hoạt động như các cổng để kiểm tra cấu hình hoặc thêm dữ liệu.
Instances: Tạo thực thể có thể tái sử dụng như baseUrl, headers, và cấu hình khác đã thiết lập.
Defaults: Thiết lập giá trị chung cho header chung (như Authorization) với các yêu cầu. Nó hữu ích khi bạn cần xác thực đến server trên mọi yêu cầu.
Các phương thức thường dùng:
axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.options(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
Caching trong React
Ta có thể caching dữ liệu trong React bằng nhiều cách như:
Local Storage
Redux Store
Giữa dữ liệu giữa mounting và unmounting
Memoization là một kỹ thuật mà chúng ta sẽ sử dụng để đảm bảo rằng chúng ta không gặp phải API nếu chúng tôi đã thực hiện một số loại yêu cầu tìm nạp nó ở một số giai đoạn đầu tiên. Việc lưu trữ kết quả của các cuộc gọi tốn kém sẽ tiết kiệm thời gian tải cho người dùng, nhờ đó tăng hiệu suất tổng thể.
Nguồn tham khảo
Last updated