ampproject / ampproject/amp-react-prototype

A safe useEffect for refs

Đang mở
#55 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
JavaScript
Star
36
Fork
6
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Mô tả

The pattern:

```
const ref = useRef();
useEffect(() => {
ref.current.addEventListener(...);
return () => ref.current.removeEventListener(...);
}, [...])

return (


{props.mode === 1 ? : }

);
```

In this pattern, it's hard to react safely to changes of `ref.current`, e.g. when a node mapped to it is deleted/changes. The "right" way to do this is to ensure that the `deps` array contains the same condition that affects `ref`. E.g. `[props.mode]` in the example above. However, it's not always obvious and easy to miss.

Some solutions are below.

/1/ Ask nicely for `deps` to be correct and hope for the best

Hopefully an "exhaustive deps" linter would not remove the extra dep.

/2/ Ban changing of Ref mapping.

I.e. disallow the example above. This could be hard with `forwardRef`.

/3/ Use state function instead of ref:

```
const [node, setNode] = useState();
useEffect(() => {...}, [node])
return <...>
```

The negative: it forces the second rerender each time the ref changes.

/4/ Use a funky `xEffectWithRef` version.

It'd manage the `ref` value internally and could look something like this:

```
function useEffectWithRef(ref, effect, deps) {
const unsubscribe = useRef(null);
const prev = useRef(null);
useEffect(() => {
return () => doUnsubscribe(prev, unsubscribe);
}, deps || []);
useEffect(() => {
const {current} = ref;
if (current !== prev.current) {
doUnsubscribe(prev, unsubscribe);
prev.current = current;
if (current) {
unsubscribe.current = effect(current);
}
}
});
}
```

The positive: it doesn't cause rerender.
A negative: one effect is executed each time, but it will almost always do nothing.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Bắt đầu với các pattern useEffect và ref được trình bày trong issue, bao gồm các phương án thay thế dựa trên state và useEffectWithRef. So sánh cách chúng xử lý các thay đổi của ref và việc cleanup; issue không xác định file đích, test hay implementation đã được thống nhất, vì vậy không có definition of done được chỉ rõ.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
javascript, react
Lĩnh vực
frontend
Loại issue
Tính năng
Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Cần làm rõ
Mức phù hợp với người mới
25/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.