Tôi có nên sử dụng một hay nhiều useEffect trong thành phần?


105

Tôi có một số tác dụng phụ cần áp dụng và muốn biết cách tổ chức chúng:

  • như một lần sử dụng
  • hoặc một số cách sử dụng

Có gì tốt hơn về mặt hiệu suất và kiến ​​trúc?

Câu trả lời:


162

Mẫu mà bạn cần tuân theo tùy thuộc vào useCase của bạn.

Đầu tiên , Bạn có thể gặp trường hợp cần thêm trình xử lý sự kiện trong lần gắn kết ban đầu và dọn dẹp chúng khi ngắt kết nối và một trường hợp khác trong đó một trình nghe cụ thể cần được dọn dẹp và thêm lại khi thay đổi chống đỡ. Trong trường hợp như vậy, sử dụng hai useEffect khác nhau sẽ tốt hơn để giữ logic liên quan cùng nhau cũng như có lợi ích về hiệu suất

useEffect(() => {
   // adding event listeners on mount here
   return () => {
       // cleaning up the listeners here
   }
}, []);

useEffect(() => {
   // adding listeners everytime props.x changes
   return () => {
       // removing the listener when props.x changes
   }
}, [props.x])

Thứ hai: Có thể có trường hợp bạn cần kích hoạt lệnh gọi API hoặc một số tác dụng phụ khác khi bất kỳ trạng thái hoặc đạo cụ nào thay đổi giữa một tập hợp. Trong trường hợp như vậy, một đơn useEffectvới các giá trị liên quan để theo dõi sẽ là một ý tưởng hay

useEffect(() => {
    // side effect here on change of any of props.x or stateY
}, [props.x, stateY])

Thứ ba: Trường hợp thứ ba khi bạn cần thực hiện các hành động khác nhau khi thay đổi các giá trị khác nhau. Trong trường hợp như vậy, hãy tách các so sánh có liên quan thành cácuseEffects

useEffect(() => {
   // some side-effect on change of props.x
}, [props.x])

useEffect(() => {
   // another side-effect on change of stateX or stateY 
}, [stateX, stateY])

1
Còn điểm trung gian giữa ví dụ Thứ haiThứ ba ở trên thì sao ?: bạn có logic chạy khi một tập hợp con của trạng thái / đạo cụ thay đổi, nhưng mỗi loại có logic riêng biệt cần chạy ngoài một số mã chung cần chạy? Bạn sẽ không sử dụng [](vì nó vẫn chỉ là một tập hợp con của trạng thái / đạo cụ mà bạn đang chờ thay đổi) nhưng bạn cũng muốn sử dụng lại mã. Bạn có sử dụng mã riêng biệt useEffectsvà đặt mã dùng chung trong một hàm mà chúng gọi riêng không?
ecoe

2
Như câu trả lời dưới đây cho thấy, nhóm React đề xuất tách các hook theo mối quan tâm, vì vậy bạn sẽ chia nó thành nhiều useEffectlệnh gọi.
hakazvaka

28
Tôi thích cách bạn viết useCase.
VerticalGrain

Chúng luôn được kích hoạt theo thứ tự định nghĩa của chúng? tức là effect1 luôn được gọi trước, sau đó là effect2?
computrius

1
@computrius ,React will apply every effect used by the component, in the order they were specified.
August Janse

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.