ampproject / ampproject/amp-react-prototype
A safe useEffect for refs
- 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
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