Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. React
Code

Các thành phần chức năng phi trạng thái vs có trạng thái trong React

by
Difficulty:BeginnerLength:LongLanguages:

Vietnamese (Tiếng Việt) translation by Thai An (you can also view the original English article)

React là một thư viện JavaScript phổ biến để xây dựng giao diện người dùng tương tác. React không quá khó để học, đó là một trong những lý do tại sao nó nhận được tất cả sự chú ý gần đây.

Mặc dù có nhiều khái niệm quan trọng cần được đề cập, các thành phần không thể phủ nhận là trái tim và linh hồn của React. Hiểu rõ về các thành phần sẽ giúp cuộc sống của bạn trở nên dễ dàng như một nhà phát triển React.

Điều kiện tiên quyết

Hướng dẫn này dành cho người mới bắt đầu đã bắt đầu học React và cần một cái nhìn tổng quan tốt hơn về các thành phần. Chúng ta sẽ bắt đầu với các khái niệm cơ bản về thành phần và sau đó chuyển sang các khái niệm khó khăn hơn như các mẫu thành phần và khi nào sử dụng các mẫu đó. Các phân loại thành phần khác nhau đã được đề cập đến như các thành phần của lớp so với các thành phần chức năng, các thành phần trạng thái không trạng thái và các thành phần container so với các thành phần hiện tại.

Trước khi bắt đầu, tôi muốn giới thiệu cho bạn đoạn mã mà chúng tôi sẽ sử dụng trong hướng dẫn này. Nó là một truy cập đơn giản được xây dựng với React. Tôi sẽ giới thiệu lại một số phần của ví dụ này trong suốt hướng dẫn.

Vậy hãy bắt đầu.

Các thành phần là gì?

Các thành phần là tự duy trì, các thực thể vi mô độc lập mô tả một phần của giao diện người dùng của bạn. Giao diện người dùng của ứng dụng có thể được chia thành các thành phần nhỏ hơn trong đó mỗi thành phần có mã, cấu trúc và API riêng.

Facebook, ví dụ, có hàng ngàn chức năng giao tiếp với nhau khi bạn xem ứng dụng web của họ. Đây là một thực tế thú vị: Facebook bao gồm 30.000 thành phần và con số này đang tăng lên. Kiến trúc thành phần cho phép bạn nghĩ về từng phần riêng biệt. Mỗi thành phần có thể cập nhật mọi thứ trong phạm vi của nó mà không lo lắng về việc nó ảnh hưởng đến các thành phần khác như thế nào.

Nếu chúng ta lấy giao diện người dùng của Facebook làm ví dụ, thanh tìm kiếm sẽ là một ứng cử viên tốt cho một thành phần. Newsfeed của Facebook sẽ tạo một thành phần khác (hoặc một thành phần chứa nhiều thành phần con). Tất cả các phương thức và lời gọi AJAX liên quan đến thanh tìm kiếm sẽ nằm trong thành phần đó.

Các thành phần cũng có thể tái sử dụng được. Nếu bạn cần cùng một thành phần ở nhiều nơi, thật dễ dàng. Với sự trợ giúp của cú pháp JSX, bạn có thể khai báo các thành phần của bạn bất cứ nơi nào bạn muốn chúng xuất hiện, và đó là nó.

Props và State

Các thành phần cần dữ liệu để làm việc. Có hai cách khác nhau mà bạn có thể kết hợp các thành phần và dữ liệu: hoặc là props hoặc trạng thái. props và nhà nước xác định những gì một thành phần ám và cách nó hoạt động. Hãy bắt đầu với props.

props

Nếu các thành phần là các hàm JavaScript đơn giản, thì các đạo cụ sẽ là đầu vào hàm. Theo tương tự, một thành phần chấp nhận đầu vào (cái mà chúng ta gọi là đạo cụ), xử lý nó và sau đó hiển thị một số mã JSX.

Stateful vs Stateless Component Component with props

Mặc dù dữ liệu trong đạo cụ có thể truy cập đến một thành phần, triết lý React là đạo cụ nên không thay đổi và từ trên xuống. Điều này có nghĩa là một thành phần cha mẹ có thể truyền bất kỳ dữ liệu nào mà nó muốn cho con của nó làm đạo cụ, nhưng thành phần con không thể sửa đổi các đạo cụ của nó. Vì vậy, nếu bạn cố gắng chỉnh sửa các đạo cụ như tôi đã làm dưới đây, bạn sẽ nhận được

Tiểu bang

Nhà nước, mặt khác, là một đối tượng thuộc sở hữu của các thành phần nơi nó được khai báo. Phạm vi của nó được giới hạn trong thành phần hiện tại. Một thành phần có thể khởi tạo trạng thái của nó và cập nhật nó bất cứ khi nào cần thiết. Trạng thái của thành phần cha mẹ thường kết thúc là đạo cụ của thành phần con. Khi trạng thái được chuyển ra khỏi phạm vi hiện tại, chúng ta gọi nó là một sự chống đỡ.

Stateful vs Stateless Component Component with State

Bây giờ chúng ta đã biết những điều cơ bản về thành phần, chúng ta hãy xem xét phân loại cơ bản của các thành phần.

Các thành phần lớp và các thành phần chức năng

Một thành phần React có thể có hai kiểu: một thành phần lớp hoặc một thành phần chức năng. Sự khác biệt giữa hai là hiển nhiên từ tên của họ.

Các thành phần chức năng

Các thành phần chức năng chỉ là các hàm JavaScript. Họ lấy một đầu vào tùy chọn, như tôi đã đề cập trước đó, là những gì chúng ta gọi là đạo cụ.

Stateful vs Stateless Components Functional Components

Một số nhà phát triển thích sử dụng các hàm mũi tên ES6 mới để xác định các thành phần. Các hàm mũi tên nhỏ gọn hơn và cung cấp cú pháp ngắn gọn để viết các biểu thức hàm. Bằng cách sử dụng một chức năng mũi tên, chúng ta có thể bỏ qua việc sử dụng hai từ khóa, hàm và trả về, và một cặp dấu ngoặc nhọn. Với cú pháp mới, bạn có thể định nghĩa một thành phần trong một dòng như thế này.

Các thành phần lớp

Các thành phần lớp học cung cấp nhiều tính năng hơn và với nhiều tính năng hơn, hành lý sẽ có nhiều hành lý hơn. Lý do chính để chọn các thành phần lớp trên các thành phần chức năng là chúng có thể có trạng thái.

Cú pháp state = {count: 1} là một phần của tính năng trường công khai. Thông tin thêm về điều này bên dưới.

Có hai cách để bạn có thể tạo một thành phần lớp. Cách truyền thống là sử dụng React.createClass (). ES6 giới thiệu một đường cú pháp cho phép bạn viết các lớp mở rộng React.Component. Tuy nhiên, cả hai phương pháp đều có nghĩa là làm điều tương tự.

Các thành phần lớp có thể tồn tại mà không có trạng thái. Đây là một ví dụ về một thành phần lớp chấp nhận một đạo cụ đầu vào và kết xuất JSX.

Chúng tôi định nghĩa một phương thức khởi tạo chấp nhận đạo cụ làm đầu vào. Bên trong hàm tạo, chúng ta gọi super () để truyền xuống bất cứ thứ gì đang được thừa kế từ lớp cha. Dưới đây là một vài chi tiết mà bạn có thể đã bỏ lỡ.

Đầu tiên, hàm tạo là tùy chọn trong khi xác định một thành phần. Trong trường hợp trên, thành phần không có trạng thái và hàm tạo không xuất hiện để làm bất cứ điều gì hữu ích. this.props được sử dụng bên trong render () sẽ làm việc bất kể liệu hàm tạo có được định nghĩa hay không. Tuy nhiên, đây là một cái gì đó từ các tài liệu chính thức:

Các thành phần lớp phải luôn gọi hàm tạo cơ sở với các đạo cụ.

Để thực hành tốt nhất, tôi sẽ khuyên bạn nên sử dụng hàm tạo cho tất cả các thành phần của lớp.

Thứ hai, nếu bạn đang sử dụng một hàm tạo, bạn cần gọi super (). Đây không phải là tùy chọn và bạn sẽ gặp lỗi cú pháp

Và điểm cuối cùng của tôi là về việc sử dụng siêu () so với siêu (đạo cụ). siêu (đạo cụ) nên được sử dụng nếu bạn đang gọi this.props bên trong constructor. Nếu không, sử dụng super () một mình là đủ.

Thành phần trạng thái và thành phần không có trạng thái

Đây là một cách phổ biến khác để phân loại các thành phần. Và các tiêu chí phân loại rất đơn giản: các thành phần có trạng thái và các thành phần không có.

Thành phần trạng thái

Các thành phần stateful luôn là các thành phần class. Như đã đề cập trước đây, các thành phần stateful có một trạng thái được khởi tạo trong hàm tạo.

Chúng ta đã tạo một đối tượng trạng thái và khởi tạo nó với một số 0. Có một cú pháp thay thế được đề xuất để làm cho các trường lớp được gọi dễ dàng hơn này. Nó không phải là một phần của đặc tả ECMAScript, nhưng nếu bạn đang sử dụng một trình chuyển đổi Babel, cú pháp này sẽ làm việc ra khỏi hộp.

Bạn có thể tránh sử dụng hàm tạo hoàn toàn với cú pháp mới này.

Bây giờ chúng ta có thể truy cập trạng thái bên trong các phương thức lớp bao gồm render (). Nếu bạn định sử dụng chúng bên trong render () để hiển thị giá trị của số đếm hiện tại, bạn cần đặt nó vào trong dấu ngoặc nhọn như sau:

Từ khóa này ở đây đề cập đến cá thể của thành phần hiện tại.

Việc khởi tạo trạng thái là không đủ - chúng ta cần có thể cập nhật trạng thái để tạo ra một ứng dụng tương tác. Nếu bạn nghĩ rằng điều này sẽ làm việc, không, nó sẽ không.

Các thành phần React được trang bị một phương thức gọi là setState để cập nhật trạng thái. setState chấp nhận một đối tượng có chứa trạng thái mới của số đếm.

SetState () chấp nhận một đối tượng làm đầu vào, và chúng ta tăng giá trị đếm trước đó lên 1, hoạt động như mong đợi. Tuy nhiên, có một nhược điểm. Khi có nhiều cuộc gọi setState đọc giá trị trước đó của trạng thái và viết một giá trị mới vào nó, chúng ta có thể kết thúc với một điều kiện chủng tộc. Điều đó có nghĩa là kết quả cuối cùng sẽ không khớp với các giá trị mong đợi.

Đây là một ví dụ mà nên làm cho nó rõ ràng cho bạn. Hãy thử điều này trong đoạn mã codesandbox ở trên.

Chúng tôi muốn setState tăng số đếm lên 100, sau đó cập nhật nó lên 1 và sau đó loại bỏ 100 giá trị đó đã được thêm vào trước đó. Nếu setState thực hiện chuyển trạng thái theo thứ tự thực tế, chúng ta sẽ nhận được hành vi mong đợi. Tuy nhiên, setState là không đồng bộ và nhiều cuộc gọi setState có thể được nhóm lại với nhau để có trải nghiệm và hiệu suất giao diện người dùng tốt hơn. Vì vậy, đoạn mã trên mang lại một hành vi khác với những gì chúng ta mong đợi.

Do đó, thay vì trực tiếp truyền một đối tượng, bạn có thể truyền vào một hàm cập nhật có chữ ký:

prevState là một tham chiếu đến trạng thái trước đó và được đảm bảo được cập nhật. đạo cụ đề cập đến đạo cụ của thành phần, và chúng ta không cần đạo cụ để cập nhật trạng thái ở đây, vì vậy chúng ta có thể bỏ qua điều đó. Do đó, chúng ta có thể sử dụng nó để cập nhật trạng thái và tránh tình trạng cuộc đua.

SetState () hiển thị lại thành phần và bạn có một thành phần làm việc có trạng thái.

Thành phần không quốc tịch

Bạn có thể sử dụng một hàm hoặc một lớp để tạo các thành phần không trạng thái. Nhưng trừ khi bạn cần phải sử dụng một móc vòng đời trong các thành phần của bạn, bạn nên đi cho các thành phần chức năng không quốc tịch. Có rất nhiều lợi ích nếu bạn quyết định sử dụng các thành phần chức năng không trạng thái ở đây; chúng dễ viết, dễ hiểu và thử nghiệm, và bạn có thể tránh hoàn toàn từ khóa này. Tuy nhiên, như React v16, không có lợi ích về hiệu suất từ ​​việc sử dụng các thành phần chức năng không trạng thái trên các thành phần lớp.

Nhược điểm là bạn không thể có móc vòng đời. Phương thức vòng đời ShouldComponentUpdate () thường được sử dụng để tối ưu hóa hiệu suất và kiểm soát thủ công những gì được hiển thị lại. Bạn chưa thể sử dụng nó với các thành phần chức năng. Tài liệu tham khảo cũng không được hỗ trợ.

Thành phần vùng chứa so với thành phần trình bày

Đây là một mẫu khác rất hữu ích khi viết các thành phần. Lợi ích của phương pháp này là logic hành vi được tách ra khỏi logic lý thuyết.

Thành phần thuyết trình

Các thành phần trình bày được kết hợp với khung nhìn hoặc cách mọi thứ trông như thế nào. Những thành phần này chấp nhận đạo cụ từ đối tác chứa của chúng và hiển thị chúng. Mọi thứ liên quan đến việc mô tả giao diện người dùng nên đến đây.

Các thành phần trình bày có thể tái sử dụng và nên tách rời khỏi lớp hành vi. Một thành phần presentational nhận dữ liệu và callbacks độc quyền thông qua các đạo cụ và khi một sự kiện xảy ra, giống như một nút được nhấn, nó thực hiện một cuộc gọi lại đến thành phần container thông qua các đạo cụ để gọi một phương thức xử lý sự kiện.

Các thành phần chức năng nên là lựa chọn đầu tiên của bạn để viết các thành phần trình bày trừ khi một trạng thái được yêu cầu. Nếu một thành phần trình bày yêu cầu một trạng thái, nó phải quan tâm đến trạng thái UI và không phải là dữ liệu thực tế. Thành phần thuyết trình không tương tác với kho lưu trữ Redux hoặc thực hiện các cuộc gọi API.

Thành phần Container

Các thành phần container sẽ xử lý phần hành vi. Một thành phần container cho biết thành phần presentational những gì nên được trả lại bằng cách sử dụng các đạo cụ. Nó không nên chứa các đánh dấu và kiểu dáng DOM giới hạn. Nếu bạn đang sử dụng Redux, một thành phần vùng chứa chứa mã gửi một hành động đến một cửa hàng. Ngoài ra, đây là nơi bạn nên đặt các cuộc gọi API và lưu kết quả vào trạng thái của thành phần.

Cấu trúc thông thường là có một thành phần thùng chứa ở phía trên để truyền dữ liệu đến các thành phần trình bày con của nó như là các đạo cụ. Điều này làm việc cho các dự án nhỏ hơn; tuy nhiên, khi dự án trở nên lớn hơn và bạn có nhiều thành phần trung gian chỉ chấp nhận đạo cụ và chuyển chúng vào các thành phần con, điều này sẽ khó chịu và khó duy trì. Khi điều này xảy ra, tốt hơn là tạo ra một thành phần container duy nhất cho thành phần lá, và điều này sẽ giảm bớt gánh nặng cho các thành phần trung gian.

Vậy PureComponent là gì?

Bạn sẽ nhận được để nghe thuật ngữ thành phần thuần túy rất thường xuyên trong các vòng tròn React, và sau đó có React.PureComponent. Khi bạn mới sử dụng React, tất cả điều này nghe có vẻ hơi khó hiểu. Một thành phần được cho là tinh khiết nếu nó được đảm bảo trả về cùng một kết quả cho cùng một đạo cụ và trạng thái. Một thành phần chức năng là một ví dụ tốt về một thành phần thuần túy bởi vì, được đưa ra một đầu vào, bạn biết những gì sẽ được trả lại.

Các thành phần lớp học có thể được tinh khiết quá miễn là đạo cụ của họ và nhà nước là bất biến. Nếu bạn có một thành phần với bộ đạo cụ và trạng thái bất biến 'sâu', API React có cái gọi là PureComponent. React.PureComponent tương tự như React.Component, nhưng nó thực hiện phương thức ShouldComponentUpdate () hơi khác một chút. ShouldComponentUpdate () được gọi trước khi một cái gì đó được hiển thị lại. Hành vi mặc định là nó trả về true để bất kỳ thay đổi nào đối với trạng thái hoặc các đạo cụ sẽ rerenders thành phần.

Tuy nhiên, với PureComponent, nó thực hiện một so sánh nông của các đối tượng. So sánh nông có nghĩa là bạn so sánh nội dung ngay lập tức của các đối tượng thay vì đệ quy so sánh tất cả các cặp khóa / giá trị của đối tượng. Vì vậy, chỉ có các tham chiếu đối tượng được so sánh, và nếu trạng thái / đạo cụ bị đột biến, điều này có thể không hoạt động như dự định.

React.PureComponent được sử dụng để tối ưu hóa hiệu suất và không có lý do gì bạn nên cân nhắc sử dụng trừ khi bạn gặp phải một số vấn đề về hiệu suất.

Suy nghĩ cuối cùng

Các thành phần chức năng không quốc tịch thanh lịch hơn và thường là một lựa chọn tốt để xây dựng các thành phần trình diễn. Bởi vì chúng chỉ là những chức năng, bạn sẽ không gặp khó khăn khi viết và hiểu chúng, và hơn nữa, chúng chết dễ dàng để kiểm tra.

Cần lưu ý rằng các thành phần chức năng không trạng thái không có mặt trên về mặt tối ưu hóa và hiệu suất vì chúng không có móc HookComponentUpdate (). Điều này có thể thay đổi trong các phiên bản tương lai của React, nơi các thành phần chức năng có thể được tối ưu hóa để có hiệu suất tốt hơn. Tuy nhiên, nếu bạn không quan trọng về hiệu suất, bạn nên dính vào các thành phần chức năng cho khung nhìn / trình bày và các thành phần lớp trạng thái cho vùng chứa.

Hy vọng rằng, hướng dẫn này đã cung cấp cho bạn một cái nhìn tổng quan cấp cao về kiến ​​trúc dựa trên thành phần và các mẫu thành phần khác nhau trong React. Bạn nghĩ gì về điều này? Chia sẻ chúng thông qua các ý kiến.

Trong vài năm qua, React đã trở nên phổ biến. Trên thực tế, chúng tôi có một số mặt hàng trong thị trường Envato có sẵn để mua, xem xét, triển khai, v.v. Nếu bạn đang tìm kiếm thêm tài nguyên xung quanh React, đừng ngần ngại kiểm tra chúng.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.