Thế nào là gắn kết đỉnh núi trong React js?


128

Tôi đang nghe thuật ngữ "gắn kết" quá nhiều lần trong khi học ReactJS. Và dường như có các phương pháp vòng đời và lỗi liên quan đến thuật ngữ này. Chính xác thì React có nghĩa là gì khi gắn kết?

Ví dụ: componentDidMount() and componentWillMount()

Câu trả lời:


138

Công việc chính của React là tìm ra cách sửa đổi DOM để phù hợp với những gì các thành phần muốn được hiển thị trên màn hình.

React làm như vậy bằng cách "gắn kết" (thêm các nút vào DOM), "ngắt kết nối" (xóa chúng khỏi DOM) và "cập nhật" (thực hiện thay đổi các nút đã có trong DOM).

Cách nút React được biểu diễn dưới dạng nút DOM và vị trí và thời điểm xuất hiện trong cây DOM được quản lý bởi API cấp cao nhất . Để hiểu rõ hơn về những gì đang diễn ra, hãy xem ví dụ đơn giản nhất có thể:

// JSX version: let foo = <FooComponent />;
let foo = React.createElement(FooComponent);

Vì vậy, những gì là foovà bạn có thể làm gì với nó? foo, hiện tại, là một đối tượng JavaScript đơn giản trông gần giống như thế này (được đơn giản hóa):

{
  type: FooComponent,
  props: {}
}

Hiện tại nó không có ở bất kỳ đâu trên trang, tức là nó không phải là một phần tử DOM, không tồn tại ở bất kỳ đâu trong cây DOM và ngoài nút phần tử React, không có đại diện có ý nghĩa nào khác trong tài liệu. Nó chỉ cho React biết những gì cần có trên màn hình nếu phần tử React này được hiển thị.Nó chưa được "gắn kết".

Bạn có thể yêu cầu React "gắn kết" nó vào thùng chứa DOM bằng cách gọi:

ReactDOM.render(foo, domContainer);

Điều này cho React biết đã đến lúc hiển thị footrên trang. React sẽ tạo một thể hiện của FooComponentlớp và gọi renderphương thức của nó . Giả sử nó biểu hiện a <div />, trong trường hợp đó React sẽ tạo một divnút DOM cho nó và chèn nó vào thùng chứa DOM.

Quá trình tạo các thể hiện và các nút DOM tương ứng với các thành phần React và chèn chúng vào DOM, được gọi là mount.

Lưu ý rằng thông thường bạn chỉ gọi ReactDOM.render()để gắn kết (các) thành phần gốc. Bạn không cần phải tự "gắn kết" các thành phần con. Mỗi lần thành phần cha mẹ gọi setState()renderphương thức của nó nói rằng một đứa trẻ cụ thể sẽ được hiển thị lần đầu tiên, React sẽ tự động "gắn kết" đứa trẻ này vào cha mẹ của nó.


9
Tôi muốn chỉ ra rằng khi bạn gọi React.createElement(FooComponent)bạn không tạo ra một thể hiện của FooComponent. foolà một đại diện DOM ảo FooComponentcòn được gọi là phần tử React. Nhưng có lẽ đó là những gì bạn có nghĩa là FooComponentloại React . Bất kể, bạn không gắn kết các thành phần trong React, bạn gọi render mà đến lượt nó có thể gắn kết thành phần nếu một nút DOM thực tế cần được tạo để thể hiện thành phần trong cây DOM. Việc gắn kết thực tế là sự kiện lần đầu tiên xảy ra.
John Leidegren

5
Việc gắn kết liên quan đến việc gắn phiên bản thành phần React vào nút DOM, điều cần thiết để thực hiện cập nhật kết xuất / tăng dần cây trên các cuộc gọi kết xuất tiếp theo.
John Leidegren

3
Tôi đã tự do chỉnh sửa câu trả lời này vì nó đã được chấp nhận nhưng có khá nhiều quan niệm sai lầm trong đó (ví dụ: bạn không thể chạy findDOMNodetrên các phần tử React).
Dan Abramov

1
@Rahamin việc ngắt kết nối xảy ra khi thành phần bị xóa / thay thế, nếu bạn điều hướng giữa các cảnh theo cách không có kết xuất, bạn không được đảm bảo tín hiệu ngắt kết nối. thành phầnWillUnmount không giống như tải trang.
John Leidegren

1
@Yossi đây là một ví dụ về việc gắn và bỏ lắp một cách rõ ràng một bộ phận trong bộ kiểm tra: stackoverflow.com/a/55359234/6225838
CPHPython 26/03/19

38

React là một khung đẳng cấu / phổ quát . Điều đó có nghĩa là có một đại diện ảo của cây thành phần UI và nó tách biệt với kết xuất thực tế mà nó xuất ra trong trình duyệt. Từ tài liệu:

React rất nhanh vì nó không bao giờ nói chuyện trực tiếp với DOM. React duy trì biểu diễn nhanh trong bộ nhớ của DOM.

Tuy nhiên, biểu diễn trong bộ nhớ đó không được gắn trực tiếp vào DOM trong trình duyệt (mặc dù nó được gọi là Virtual DOM, đây là một cái tên đáng tiếc và khó hiểu cho khung ứng dụng phổ quát) và nó chỉ là một dữ liệu giống như DOM- cấu trúc đại diện cho tất cả các cấu trúc phân cấp UI và dữ liệu meta bổ sung. Virtual DOM chỉ là một chi tiết triển khai.

"Chúng tôi nghĩ rằng nền tảng thực sự của React chỉ đơn giản là ý tưởng của các thành phần và thành phần: có thể mô tả những gì bạn muốn kết xuất theo cách khai báo. Đây là những phần được chia sẻ bởi tất cả các gói khác nhau này. Các phần của React dành riêng cho kết xuất nhất định mục tiêu thường không phải là những gì chúng ta nghĩ đến khi chúng ta nghĩ về React. " - Phản ứng blog js

Vì vậy, kết luận là React đang kết xuất thuyết bất khả tri , có nghĩa là nó không quan tâm đến đầu ra cuối cùng là gì. Nó có thể là Cây DOM trong trình duyệt, nó có thể là XML, các thành phần gốc hoặc JSON.

"Khi chúng ta xem xét các gói như Reac -igen, Reac-art, Reac-canvas và Reac-ba, rõ ràng rằng vẻ đẹp và bản chất của React không liên quan gì đến trình duyệt hoặc DOM." - Phản ứng blog js

Bây giờ, bạn đã biết React hoạt động như thế nào, thật dễ dàng để trả lời câu hỏi của bạn :)

Gắn kết là quá trình xuất biểu diễn ảo của một thành phần vào biểu diễn UI cuối cùng (ví dụ: DOM hoặc Thành phần gốc).

Trong trình duyệt có nghĩa là xuất phần tử React thành phần tử DOM thực tế (ví dụ: phần tử div hoặc li HTML ) trong cây DOM. Trong một ứng dụng gốc có nghĩa là xuất một phần tử React thành một thành phần gốc. Bạn cũng có thể viết trình kết xuất của riêng mình và xuất các thành phần React thành JSON hoặc XML hoặc thậm chí XAML nếu bạn có can đảm.

Vì vậy, trình xử lý gắn / ngắt kết nối rất quan trọng đối với ứng dụng React, bởi vì bạn chỉ có thể chắc chắn một thành phần được xuất / kết xuất khi được gắn . Tuy nhiên, componentDidMounttrình xử lý chỉ được gọi khi kết xuất thành biểu diễn UI thực tế (DOM hoặc Thành phần gốc) chứ không phải nếu bạn kết xuất thành chuỗi HTML trên máy chủ bằng cách sử dụngrenderToString , điều này có nghĩa, vì thành phần này không thực sự được gắn cho đến khi nó đạt đến trình duyệt và thực thi trong đó.

Và, vâng, Mounting cũng là một cái tên không may / khó hiểu, nếu bạn hỏi tôi. IMHO componentDidRendercomponentWillRendersẽ là tên tốt hơn nhiều.


6
Ai đó chỉ cho tôi câu trả lời này từ một diễn đàn khác. Tôi không nghĩ componentDidRenderlà một sự thay thế componentDidMountbởi vì thành phần có thể kết xuất nhiều lần khi đạo cụ thay đổi sau khi nó được gắn một lần.
Gaurav

@TheMinister Nó được gọi là thư viện "DOM ảo" vì nó không bắt đầu như là đẳng cấu, nhưng thực sự gắn liền với DOM ngay từ đầu. Đó là một suy nghĩ lại để làm cho nó đẳng hình.
Isiah Meadows

Vì vậy, mount có thể hoán đổi với render ? Trong trường hợp đó, có đúng là một thành phần được gắn / kết xuất cho từng giả thuyết sau đây không ?: (id === that.id) ? <Component /> : null| /app/items/:id| this.setState(...).
Cody

1
Liên kết đến / Reac-js-the-king-of-Universal-apps / đã bị hỏng
Michael Freidgeim

Tôi đã chỉnh sửa bài đăng hai lần để xóa liên kết bị hỏng /react-js-the-king-of-universal-apps/( với các bình luận chỉnh sửa đề cập rõ ràng rằng đó là một liên kết bị hỏng ), nhưng các đồng nghiệp đã từ chối chỉnh sửa cả hai lần . Ai đó có thể hướng dẫn cho tôi những gì sai trong việc chỉnh sửa một câu trả lời và xóa một liên kết bị hỏng?
Aaditya Sharma

12

Gắn kết đề cập đến thành phần trong React (các nút DOM được tạo) được gắn vào một phần của tài liệu. Đó là nó!

Bỏ qua React, bạn có thể nghĩ hai chức năng gốc này là gắn kết:

thay thế

appendChild

Đây có thể là các chức năng phổ biến nhất mà React sử dụng để gắn kết bên trong.

Hãy nghĩ về:

thành phầnWillMount === trước khi gắn kết

Và:

thành phầnDidMount === sau khi gắn kết


Nếu gắn tương tự appendChild, là rendergì?
Deke

Tôi nghĩ bạn có thể nói renderlà phương pháp thực tế sẽ tự lắp. Vì vậy, componentWillMount== trước, render== thực hiện chèn DOM và componentDidMount== sau khi gắn kết (hoặc renderđã gọi API DOM để chèn thành phần và hoạt động không đồng bộ đó đã hoàn thành đầy đủ)
Rob

8

https://facebook.github.io/react/docs/tutorial.html

Ở đây, thành phầnDidMount là một phương thức được gọi tự động bởi React khi một thành phần được hiển thị.

Khái niệm là bạn đang nói với ReactJS, "vui lòng lấy thứ này, hộp bình luận này hoặc quay hình ảnh hoặc bất cứ thứ gì tôi muốn trên trang trình duyệt, và tiếp tục và thực sự đưa nó lên trang trình duyệt. Khi xong, hãy gọi chức năng của tôi mà tôi đã ràng buộc để componentDidMounttôi có thể tiến hành. "

componentWillMountLà ngược lại. Nó sẽ bắn ngay lập tức TRƯỚC KHI thành phần của bạn.

Xem thêm tại đây https://facebook.github.io/react/docs/component-specs.html

Cuối cùng, thuật ngữ "mount" dường như là duy nhất đối với Reac.js. Tôi không nghĩ đó là một khái niệm javascript chung hay thậm chí là một khái niệm trình duyệt chung.


vậy gắn kết có thể được gọi là "đặt"?
cổng

Tôi sẽ nói như vậy, vâng.
Ross Presser

Tôi sẽ nói rằng trích dẫn này có phần sai lệch, vì nó chỉ được gọi sau khi kết xuất ban đầu , không phải trên kết xuất lại gây ra bởi các bản cập nhật. Sau đó componentDidUpdateđược gọi thay thế.
Hannes Johansson

+1 cho facebook này.github.io/react/docs/ Sự , mô tả ở đó xác nhận nó được đặt;)
cổng

5

Gắn kết đề cập đến tải trang ban đầu khi thành phần React của bạn được hiển thị lần đầu tiên. Từ tài liệu React cho Mounting: componentDidMount:

Invoked once, only on the client (not on the server), immediately after the initial rendering occurs. At this point in the lifecycle, the component has a DOM representation which you can access via React.findDOMNode(this).

Bạn có thể đối chiếu điều này với hàm thành phầnDidUpdate, được gọi mỗi lần React kết xuất lại (ngoại trừ mount ban đầu).


3

Mục tiêu chính của React js là tạo ra các thành phần có thể tái sử dụng. Ở đây, các thành phần là các phần riêng biệt của một trang web. Ví dụ: trong trang web, tiêu đề là một thành phần, chân trang là một thành phần, thông báo bánh mì nướng là một thành phần và v.v ... Thuật ngữ "mount" cho chúng ta biết rằng các thành phần này được tải hoặc hiển thị trong DOM. Đây là nhiều API và phương thức cấp cao nhất xử lý vấn đề này.

Để làm cho nó đơn giản, được gắn có nghĩa là thành phần đã được tải vào DOM và không đếm được có nghĩa là các thành phần đã bị xóa khỏi DOM.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.