Phụ thuộc trống với useMemo hoặc useCallback VS useRef


9

Trong vấn đề GitHub này, về cơ bản tôi đã đề xuất thay đổi:

x = useCallback( ... , []);

Đến:

x = useRef( ... ).current;

Hai cái này giống nhau nhưng với useRefReact không so sánh các phụ thuộc.

Mà một câu trả lời đi kèm với một câu hỏi:

Có bao giờ tình huống sử dụngMemo hoặc useCallback không phụ thuộc sẽ là lựa chọn tốt hơn useRef không?

Tôi không thể nghĩ ra một cái, nhưng tôi có thể đã bỏ qua một số trường hợp sử dụng.

Vì vậy, bất cứ ai có thể nghĩ về tình huống như vậy?

Câu trả lời:


5

Tài liệu API trên mỗi React Hook:

Hãy nhớ rằng useRef không thông báo cho bạn khi nội dung của nó thay đổi. Việc đột biến thuộc tính .c hiện không gây ra kết xuất lại ... Sử dụng tham chiếu gọi lại đảm bảo rằng ngay cả khi một thành phần con hiển thị nút được đo sau đó (ví dụ: để đáp ứng với một lần nhấp), chúng tôi vẫn nhận được thông báo về nó trong phần cha mẹ thành phần và có thể cập nhật các phép đo.

Bạn có thể đọc thêm về nó ở đâyở đây .


Tôi đoán điều này trả lời câu hỏi, nhưng tôi nghi ngờ điều này là không chính xác. Trong ví dụ React của hộp cát, việc thay đổi useCallback(x,[])thành useRef(x)hoạt động tương tự.
Izhaki

useRef(x).currentđó là.
Izhaki

Tôi hy vọng tôi sai, nhưng tôi đã đưa ra một lý do tại sao các tài liệu sai: github.com/reactjs/reactjs.org/issues/2570
Izhaki 15/11/19

Tôi không hoàn toàn chắc chắn về useCallback(cb, [])vs useRef(cb).currentbản thân mình. Mặc dù, useMemo(cb, [])khác với useRef(cb).currentý nghĩa rằng useMemo, "sẽ chỉ tính lại giá trị ghi nhớ khi một trong các phụ thuộc đã thay đổi." Versus useRefluôn luôn tính toán lại giá trị bất kể điều gì.
irasuna

useRefkhông bao giờ tính toán lại - nó luôn trả về giá trị ban đầu.
Izhaki

1

Mặc dù bạn có thể sử dụng useRef để mô phỏng useCallback hoặc với một phụ thuộc trống, Bạn không thể sử dụng nó cho tất cả các tình huống có thể có của useCallback để nhớ lại khi có bất kỳ phụ thuộc nào thay đổi.

Ngoài ra, nó sẽ không tạo ra nhiều sự khác biệt về hiệu suất nếu bạn sử dụng useCallback with empty dependencyhoặc sử dụngRef vì nó không phải thực hiện bất kỳ so sánh nặng nề nào.

Ngoài ra nếu bạn thay đổi thực hiện chức năng một chút để bạn phải tạo lại nó trên một thay đổi param cụ thể, bạn có thể chỉ cần cập nhật việc thực hiện với useCallbackvà thêm vào thông số phụ như là phụ thuộc. Tuy nhiên, nếu bạn triển khai nó với useRef, bạn phải quay lạiuseCallback


1
Cảm ơn. Như tiêu đề cho thấy, đây là một trường hợp phụ thuộc hoàn toàn trống rỗng.
Izhaki

1
@Izhaki Tôi hiểu câu hỏi của bạn là phụ thuộc hoàn toàn trống rỗng và đó là lý do tại sao tôi đã đề cập rằng không có sự khác biệt nào trong trường hợp phụ thuộc trống. Nhưng khi bạn cố gắng thêm nhiều thay đổi, bạn có thể cần khá nhiều công cụ tái cấu trúc
Shubham Khatri

0

Bởi vì đầu ra của useRef (() => {...}). Hiện tại là có thể thay đổi.

Điều này có thể gây ra tác dụng phụ kỳ lạ trong mã của bạn. Tôi có thể thay đổi giá trị của hiện tại bất cứ lúc nào. https://codesandbox.io/s/confident-monad-vjeuw

Đó sẽ là usecase vì không muốn sử dụng useRef


1
Nhưng x = useRef(value).currentkhông bao giờ trả lại một trường hợp có thể thay đổi - refkhông bao giờ được trả lại; currentLà. Điều đó giống với useCallbackphiên bản.
Izhaki
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.