Tại sao các tài liệu React khuyên bạn nên thực hiện AJAX trong componentDidMount, không phải componentWillMount?


102

Tiêu đề nói lên tất cả. Tôi hiểu tại sao lại componentDidMountphù hợp với bất kỳ thứ gì yêu cầu quyền truy cập DOM, nhưng yêu cầu AJAX không nhất thiết hoặc thường cần điều này.

Đưa cái gì?


@FurkanO Tôi nghĩ ý của anh ấy là quyền truy cập vào các phần tử DOM được kết xuất bởi thành phần. Và anh ấy hoàn toàn đúng bởi vì nếu bạn cố gắng truy cập các phần tử đã nói trong componentWillMountđó sẽ thất bại vì thành phần đó ... không gắn kết.
ZekeDroid

@AlanH. Đã xóa câu hỏi của tôi, tất nhiên bạn có quyền truy cập vào dom trên componentDidMount. Đây là một quy tắc, không có gì để giải thích về nó. Cảm ơn.
FurkanO

Theo ý kiến ​​của tôi, tại sao chúng ta gọi hàm Ajax sau componentDidMount là trước tiên chúng ta phải đảm bảo rằng Element đang hiển thị trơn tru ngay từ đầu. Sau đó, chúng tôi có thể thực hiện cuộc gọi ajax. Nếu chúng ta gọi ajax lỗi đầu tiên và một cái gì đó xảy ra nó sẽ gây ra vấn đề về render
Faris Rayhan

Câu trả lời:


62

componentDidMountlà cho các phản ứng phụ. Thêm trình nghe sự kiện, AJAX, thay đổi DOM, v.v.

componentWillMounthiếm khi hữu ích; đặc biệt nếu bạn quan tâm đến kết xuất phía máy chủ (thêm trình xử lý sự kiện gây ra lỗi và rò rỉ, và nhiều thứ khác có thể xảy ra sai sót).

Có một cuộc thảo luận về việc loại bỏ componentWillMountkhỏi các thành phần lớp vì nó phục vụ cùng mục đích với hàm tạo. Nó sẽ vẫn còn trên createClasscác thành phần.


1
Thêm trình xử lý sự kiện gây ra lỗi và rò rỉ mọi lúc trên máy chủ hay chỉ trong componentWillMount? Tôi không thực sự thấy sự khác biệt.
Alan H.

18
@Alan - Nếu bạn đang sử dụng React trên cả clientide và serveride, bạn sẽ thấy rằng mọi thứ bên trong componentWillMountsẽ được thực thi trên bản kết xuất phía máy chủ. Bánh xe nếu bạn đang sử dụng componentDidMountthì điều đó sẽ chỉ được thực hiện trên máy khách. Do đó, đặt những thứ componentWillMountthực hiện các tương tác bên ngoài hoặc liên kết với các sự kiện, v.v., không phải là một ý tưởng tuyệt vời. Nếu bạn không có kế hoạch hiển thị các thành phần của mình trên máy chủ, nó vẫn không phải là một ý tưởng hay chỉ vì khả năng di động của mã. Tất cả đều nằm ngoài lý do chính khiến nó tệ được giải thích trong câu trả lời của @daniula.
Mike Driver

3
componentWillMount được chạy trên máy chủ, nhưng componentWillUnmount (nơi bạn xóa người nghe) thì không. Điều này sẽ khiến bạn thêm người nghe và không bao giờ xóa chúng.
Brigand

Những người trong nhóm cốt lõi của React đang xem xét việc xóa componentWillMount khỏi các phiên bản trong tương lai.
cchamberlain

1
@AnkitSinghaniya nó sẽ phá vỡ kết xuất máy chủ và các thử nghiệm đơn vị nông.
Brigand

36

Tôi cũng gặp vấn đề tương tự ngay từ đầu. Tôi đã quyết định thử đưa ra các yêu cầu componentWillMountnhưng cuối cùng lại gặp nhiều vấn đề nhỏ khác nhau.

Tôi đã kích hoạt hiển thị khi cuộc gọi ajax kết thúc với dữ liệu mới. Tại một số thời điểm, việc hiển thị thành phần mất nhiều thời gian hơn là nhận được phản hồi từ máy chủ và tại thời điểm này, lệnh gọi lại ajax đang kích hoạt hiển thị trên thành phần chưa được gắn kết. Đây là loại vỏ có cạnh nhưng có lẽ còn nhiều hơn nữa, vì vậy sẽ an toàn hơn khi sử dụng componentDidMount.


Được rồi, cảm ơn. Nghĩ rằng nó có thể là một cái gì đó như vậy, nhưng bạn nói đúng, thật bất ngờ khi yêu cầu ajax có thể hoàn thành trước khi kết xuất thực hiện.
Alan H.

1
@daniula Bạn có chắc không? Làm cách nào để yêu cầu AJAX kết thúc trước khi kết xuất?
Leon Grapenthin

4
Đây là thế giới không đồng bộ của trình duyệt. Bạn đừng bao giờ cho rằng một chức năng sẽ luôn nhanh hơn chức năng còn lại. Như tôi đã đề cập, đó là trường hợp cạnh và có lẽ có nghĩa là bạn nên tối ưu hóa quy trình kết xuất của mình nhưng sử dụng phương pháp vòng đời phù hợp sẽ giúp cuộc sống của bạn dễ dàng hơn nhiều vào thời điểm này.
daniula

1
Hàm tạo lớp @SooChengKoh ES6 tương đương với componentWillMount, vì vậy bạn vẫn nên tiếp tục sử dụng componentDidMountcho các cuộc gọi ajax của mình.
daniula

1
@SooChengKoh - Chắc chắn không nên làm bất cứ điều gì trong hàm tạo sẽ dẫn đến trạng thái phải được đặt, điều đó sẽ dẫn đến các điều kiện chạy đua trên máy khách và máy chủ. Bạn không bao giờ nên gọi setStatemột hàm tạo thành phần và bạn không có cách nào xác định khi nào lệnh gọi AJAX sẽ hoàn tất. twitter.com/dan_abramov/status/576453138598723585
cchamberlain

3

Theo tài liệu, cài đặt trạng thái trong componentWillMountsẽ không kích hoạt hiển thị lại. Nếu lệnh gọi AJAX không bị chặn và bạn trả về một Promisecập nhật trạng thái của thành phần thành công, thì có khả năng phản hồi đến sau khi thành phần đã được hiển thị. Như componentWillMountkhông kích hoạt kết xuất lại, bạn sẽ không có hành vi như bạn mong đợi, đó là thành phần đang được hiển thị với dữ liệu được yêu cầu.

Nếu bạn sử dụng bất kỳ thư viện thông lượng nào và dữ liệu được yêu cầu kết thúc trong cửa hàng mà thành phần được kết nối (hoặc kế thừa từ một thành phần được kết nối) thì điều này sẽ không thành vấn đề vì việc nhận dữ liệu đó, rất có thể, sẽ thay đổi đạo cụ cuối cùng.


1
componentWillMountkhông kích hoạt kết xuất lại chỉ vì một trạng thái mới được xác định trước kết xuất đầu tiên. Nhưng nếu setStateđược gọi trong lệnh gọi lại AJAX, nó chắc chắn sẽ được gọi sau lần kết xuất đầu tiên và nó sẽ kích hoạt kết xuất lại.
webdif
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.